Modifed protocal module to accept non spec confirming ircd's, Daemonize bot
This commit is contained in:
parent
37d0d9837e
commit
2b56dabda7
26
IRC.py
26
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
|
||||
|
|
77
client.py
77
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()
|
Loading…
Reference in New Issue