summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatt Arnold <matt@thegnuguru.org>2022-03-08 14:17:15 -0500
committerMatt Arnold <matt@thegnuguru.org>2022-03-08 14:17:15 -0500
commit2b56dabda7d563945a9aa2d76560802772eb7566 (patch)
tree4361ee09563e9da10b49455664dae4116361fb6e
parent37d0d9837efd4409f92e16d55120778c4ad04c11 (diff)
Modifed protocal module to accept non spec confirming ircd's, Daemonize bot
-rw-r--r--IRC.py26
-rw-r--r--client.py77
2 files changed, 64 insertions, 39 deletions
diff --git a/IRC.py b/IRC.py
index 90ef1fa..111de68 100644
--- a/IRC.py
+++ b/IRC.py
@@ -4,6 +4,8 @@ import socket
 import sys
 import irctokens
 import time
+import logging
+
 class IRCBadMessage(Exception):
     pass
 class IRCError(Exception):
@@ -38,10 +40,11 @@ class IRCBot:
 
     irc = None
 
-    def __init__(self, sock, config=None):
+    def __init__(self, sock, config=None, isBad=False):
         self.irc = sock
         self.connected = False
         self.config = config
+        self.badircd = isBad
 
     def send_cmd(self, line):
         """Send an IRC Command, takes an IRC command string without the CRLF
@@ -68,7 +71,7 @@ class IRCBot:
     
     def send_quit(self, quitmsg):
         msg = irctokens.build("QUIT", [quitmsg])
-        print(msg)
+        logging.debug(msg)
         self.send_cmd(msg)
 
     def send_action(self, action_msg, dst):
@@ -82,30 +85,35 @@ class IRCBot:
             self.config["nick"] = botnick
             self.config["channel"] = channel
             self.config["nickpass"] = botnickpass
-        print("Connecting to: " + server)
+        logging.debug("Connecting to: " + server)
         self.irc.connect((self.config["hostname"], self.config["port"]))
         self.connected = True
 
         # Perform user registration
         usermsg = irctokens.build("USER", [botnick, "0","*", "RabbitEars Bot"]).format()
-        print(usermsg)
+        logging.debug(usermsg)
         self.send_cmd(usermsg)
         nickmsg = irctokens.build("NICK", [botnick])
         self.send_cmd(nickmsg)
-    
+        if self.badircd:
+            time.sleep(5)
+            authmsg = irctokens.build("NICKSERV", ['IDENTIFY', self.config['nickpass']])
+            self.send_cmd(authmsg)
+            time.sleep(5)
+            self.on_welcome([self.config["hostname"]])
     def get_response(self):
         # Get the response
         resp = self.irc.recv(4096).decode("UTF-8")
         msg = parsemsg(resp)
         nwmsg = irctokens.tokenise(resp)
-        printred(nwmsg.command)
+        logging.info(nwmsg.command)
         if nwmsg.command == "001":
             self.on_welcome(nwmsg.params)
         if nwmsg.command == "ERROR":
             raise IRCError(str(nwmsg.params[0]))
         if nwmsg.command == 'PING':
-            print('Sending pong')
-            self.irc.send(
-                bytes('PONG ' + LINEEND, "UTF-8"))
+            logging.debug('Sending pong')
+            pongmsg = irctokens.build("PONG", [nwmsg.params[0]])
+            self.send_cmd(pongmsg)
 
         return msg
diff --git a/client.py b/client.py
index 7787a9c..062a04e 100644
--- a/client.py
+++ b/client.py
@@ -9,6 +9,15 @@ import sys
 import irctokens
 import json
 import sqlite3
+import logging
+from daemonize import Daemonize
+
+logging.basicConfig(filename='bot.log', encoding='utf-8', level=logging.DEBUG)
+
+class NullDevice:
+    def write(self,s):
+        pass
+
 LINEEND = '\r\n'
 # IRC Config
 config = None
@@ -16,27 +25,33 @@ with open('config.json') as f:
     jld = f.read()
     config = json.loads(jld)
 
-con = sqlite3.connect(config['db'])
-cur = con.cursor()
 
 
 
 # Need to pass the IRCBot class a socket the reason it doesn't do this itself is 
 # so you can set up TLS or not as you need it
 # These provide good defaults. But your milage may vary
-oursock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-context = ssl.SSLContext()
-context.check_hostname = False
-context.verify_mode = ssl.CERT_NONE
-oursock = context.wrap_socket(oursock, server_hostname=config['hostname'])
-irc = IRCBot(oursock)
-irc.connect(config['hostname'],
-    config['port'],
-    config['channel'],
-    config['nick'],
-    config['nickpass'])
+def do_connect():
+    oursock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    context = ssl.SSLContext()
+    context.check_hostname = False
+    context.verify_mode = ssl.CERT_NONE
+    oursock = context.wrap_socket(oursock, server_hostname=config['hostname'])
+
+    irc = IRCBot(oursock, isBad=config["isBad"])
+    irc.connect(config['hostname'],
+        config['port'],
+        config['channel'],
+        config['nick'],
+        config['nickpass'])
+    return irc
+
+def hup_handle(sig, fr):
+    sys.exit()
 
 def do_mean():
+    con = sqlite3.connect(config['db'])
+    cur = con.cursor()
     qr = cur.execute("SELECT count(*) from mean").fetchone()
     maxrows = int(qr[0])
     slrow = str(random.randint(1, maxrows))
@@ -59,22 +74,24 @@ def generate_response(person, message):
     else:
         return None
 
-while True:
-    try:
+def do_main_loop():
+    irc = do_connect()
+    while True:
+        try:
 
-        text = irc.get_response()
-        print(text[0],text[1],text[2])
-        if text[1] == 'PRIVMSG' and text[2][0] == config['channel']:
-            r = generate_response(text[0],text[2][1])
-            if r is not None:
-                irc.send_privmsg(config['channel'],r)
-    except KeyboardInterrupt:
-        irc.send_quit("Ctrl-C Pressed")
-        msg = oursock.recv(4096)
-        print(msg)
-        sys.exit(0)
-    except IRCError as e:
-        printred(e)
-        sys.exit(1)
+            text = irc.get_response()
+            logging.debug(text[0],text[1],text[2])
+            if text[1] == "MODE": # in leiu of RPL_WELCOME
+                botmode = irctokens.build("MODE", [config['nick'], '+B'])
+                irc.send_cmd(botmode)
+            if text[1] == 'PRIVMSG' and text[2][0] == config['channel']:
+                r = generate_response(text[0],text[2][1])
+                if r is not None:
+                    irc.send_privmsg(config['channel'],r)
+        except IRCError as e:
+            logging.error(e)
+            sys.exit(1)
 
-    
+pid = "bot.pid"
+daemon = Daemonize(app="theodebot", pid=pid, action=do_main_loop)
+daemon.start()
\ No newline at end of file