diff options
author | Matt Arnold <matt@thegnuguru.org> | 2022-03-08 14:17:15 -0500 |
---|---|---|
committer | Matt Arnold <matt@thegnuguru.org> | 2022-03-08 14:17:15 -0500 |
commit | 2b56dabda7d563945a9aa2d76560802772eb7566 (patch) | |
tree | 4361ee09563e9da10b49455664dae4116361fb6e | |
parent | 37d0d9837efd4409f92e16d55120778c4ad04c11 (diff) |
Modifed protocal module to accept non spec confirming ircd's, Daemonize bot
-rw-r--r-- | IRC.py | 26 | ||||
-rw-r--r-- | client.py | 77 |
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 |