Change class instantiation, add a bit of error handling

trunk
mio 2018-09-13 20:12:18 +00:00
parent 02aff49ea0
commit 797ed660dd
3 changed files with 52 additions and 67 deletions

33
irc.py
View File

@ -1,16 +1,12 @@
import socket import socket
from sys import exit
class IRC: class IRC:
"""A set of methods for basic IRC communication.""" """Methods for basic IRC communication."""
def __init__(self): debug = False
self.debug = False
self.sock = ""
def is_debug(self, boolean):
self.debug = boolean
def send(self, command, text, *args, **kwargs): def send(self, command, text, *args, **kwargs):
"""Send messages given the IRC command and text. Optionally specify a """Send messages given the IRC command and text. Optionally specify a
message recipient with `recvr=user`.""" message recipient with `recvr=user`."""
@ -21,23 +17,23 @@ class IRC:
print("[debug][send] " + command + " " + recvr + text) print("[debug][send] " + command + " " + recvr + text)
bs = bytes(command + " " + recvr + text + "\r\n", "utf-8") bs = bytes(command + " " + recvr + text + "\r\n", "utf-8")
try: try:
if kwargs.get("sock", "") != "": self.sock.sendall(bs)
public_ss = kwargs.get("sock", "") except BrokenPipeError as err:
public_ss.sendall(bs) if self.debug:
else: print("[debug] " + str(err) + " at `" + \
self.sock.sendall(bs) bs.decode("utf-8").strip() + "`")
except BrokenPipeError:
print("[debug][broken_pipe_err] " + command + " " + recvr + text)
pass pass
def connect(self, server, bot_nick): def connect(self, server, bot_nick):
"""Connect to the server and sends user/nick information.""" """Connect to the server and sends user/nick information."""
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try:
self.sock.connect(server) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect(server)
except ConnectionError as err:
exit("[debug] " + str(err))
self.send("USER", bot_nick + " " + bot_nick + " " + \ self.send("USER", bot_nick + " " + bot_nick + " " + \
bot_nick + " " + bot_nick) bot_nick + " " + bot_nick)
self.send("NICK", bot_nick) self.send("NICK", bot_nick)
return self.sock
def disconnect(self, resp_msg, quit_msg, admin_user): def disconnect(self, resp_msg, quit_msg, admin_user):
"""Notify the admin user and disconnect from the server.""" """Notify the admin user and disconnect from the server."""
@ -45,6 +41,7 @@ class IRC:
self.send("QUIT", ":" + quit_msg) self.send("QUIT", ":" + quit_msg)
def receive(self, *args, **kwargs): def receive(self, *args, **kwargs):
"""Get messages from the connected socket."""
data = self.sock.recv(2040).decode("utf-8").strip("\n\r") data = self.sock.recv(2040).decode("utf-8").strip("\n\r")
if self.debug: if self.debug:
print("[debug][recv] " + data) print("[debug][recv] " + data)
@ -56,7 +53,7 @@ class IRC:
self.send("PONG", ":" + line.split(":", 2)[1].split(" ", 1)[0]) self.send("PONG", ":" + line.split(":", 2)[1].split(" ", 1)[0])
def join_channels(self, channels): def join_channels(self, channels):
"""Join channels from a list in the config.""" """Join channels given a list of channel names."""
for c in channels: for c in channels:
if c.strip() != "" or c.strip() != "#": if c.strip() != "" or c.strip() != "#":
self.send("JOIN", c) self.send("JOIN", c)

View File

@ -1,49 +1,56 @@
from os import _exit from sys import exit
from random import randint from random import randint
from time import sleep
import config as cfg import config as cfg
from irc import IRC from irc import IRC
class Ramen: class Ramen:
"""Functions for ramenkan."""
def __init__(self): irc = IRC()
self.irc = IRC() irc.debug = cfg.debug
self.irc.is_debug = cfg.debug
self.bot_nick = cfg.bot_nick
self.admin_user = cfg.admin_user
self.admin_code = cfg.admin_code
self.req_prefix = cfg.req_prefix
def attach(self, socket): def run(self):
self.sock = socket """Connect to the server and channels, initialise the listener in the
application loop."""
self.irc.connect(cfg.server, cfg.bot_nick)
self.irc.join_channels(cfg.channels)
while 1:
sleep(2)
data = self.irc.receive(debug=cfg.debug)
self.irc.keep_alive(data)
self.msg = self.irc.parse_msg(data, cfg.req_prefix)
for chan in cfg.channels:
self.handle(chan)
def handle(self, channel, data): def handle(self, channel):
"""Listen for requests in a channel and match responses.""" """Listen for requests in a channel and pass them to handler
self.msg = self.irc.parse_msg(data, self.req_prefix) functions."""
if self.msg["req_chan"] == cfg.bot_nick:
if self.msg["req_chan"] == self.bot_nick:
# Respond to some commands only from admin user # Respond to some commands only from admin user
if self.msg["user"].lower() == self.admin_user.lower() and \ if self.msg["user"].lower() == cfg.admin_user.lower() and \
self.admin_code in self.msg["req"]: cfg.admin_code in self.msg["req"]:
self.handle_admin_req(self.msg["req"], self.admin_user) self.handle_admin_req(self.msg["req"], cfg.admin_user)
# Respond only in the channel the request was made # Respond only in the channel the request was made
if channel == self.msg["req_chan"]: if channel == self.msg["req_chan"]:
# General commands # General commands
if self.msg["req"] == "rollcall" or self.msg["req"] == "help": if self.msg["req"] == "rollcall" or self.msg["req"] == "help":
self.handle_rollcall() self.handle_rollcall()
elif self.msg["req"] == ("water " + self.bot_nick): elif self.msg["req"] == ("water " + cfg.bot_nick):
self.handle_water() self.handle_water()
elif self.msg["req"] == ("botsnack " + self.bot_nick): elif self.msg["req"] == ("botsnack " + cfg.bot_nick):
self.handle_botsnack() self.handle_botsnack()
def handle_admin_req(self, req, admin_user): def handle_admin_req(self, req, admin_user):
"""Perform admin functions."""
if "exit" in req: if "exit" in req:
self.irc.send("PRIVMSG", "Okay, okay, I'll leave. (´・ω・`)", \ self.irc.send("PRIVMSG", "Okay, okay, I'll leave. (´・ω・`)", \
recvr=admin_user, sock=self.sock) recvr=admin_user)
self.irc.send("QUIT", ":noodling off", sock=self.sock) self.irc.send("QUIT", ":noodling off")
_exit(0) exit("Shutting down ...")
def handle_rollcall(self): def handle_rollcall(self):
resp = ( resp = (
@ -53,8 +60,7 @@ class Ramen:
"!help " "!help "
"Support: +81 012-700-1MIO どうぞめしあがれ。" "Support: +81 012-700-1MIO どうぞめしあがれ。"
) )
self.irc.send("PRIVMSG", resp, recvr=self.msg["req_chan"], \ self.irc.send("PRIVMSG", resp, recvr=self.msg["req_chan"])
sock=self.sock)
def handle_water(self): def handle_water(self):
resp = [ resp = [
@ -64,8 +70,12 @@ class Ramen:
"Water Level [/////////] 200% - Thanks! (^▽^)" "Water Level [/////////] 200% - Thanks! (^▽^)"
] ]
self.irc.send("PRIVMSG", resp[randint(0, len(resp)-1)], \ self.irc.send("PRIVMSG", resp[randint(0, len(resp)-1)], \
recvr=self.msg["req_chan"], sock=self.sock) recvr=self.msg["req_chan"])
def handle_botsnack(self): def handle_botsnack(self):
self.irc.send("PRIVMSG", "Ramen time anytime! ヽ(´▽`)/", \ self.irc.send("PRIVMSG", "Ramen time anytime! ヽ(´▽`)/", \
recvr=self.msg["req_chan"], sock=self.sock) recvr=self.msg["req_chan"])
app = Ramen()
app.run()

22
run.py
View File

@ -1,22 +0,0 @@
from time import sleep
import config as cfg
from irc import IRC
from ramen import Ramen
irc = IRC()
irc.is_debug(cfg.debug)
socket = irc.connect(cfg.server, cfg.bot_nick)
irc.join_channels(cfg.channels)
ramen = Ramen()
# Have run.py and ramen.py share the same socket connection
ramen.attach(socket)
while 1:
sleep(2)
data = irc.receive(debug=cfg.debug)
irc.keep_alive(data)
for chan in cfg.channels:
ramen.handle(chan, data)