import irc
import string
class Recipient:
def __init__(self, interface, name):
self.__interface = interface
self.__name = name
def name(self):
return self.__name
def tell(self, text):
"""Tell the recipient something"""
return self.write_raw(["PRIVMSG", self.__name], text)
def notice(self, text):
"""Send a notice to the recipient"""
return self.write_raw(["NOTICE", self.__name], text)
def ctcp(self, command, text):
"""Send a CTCP command to the recipient"""
return self.tell("\001%s %s\001" % (irc.upper(command), text))
def act(self, text):
"""Send an action to the recipient"""
return self.ctcp("ACTION", text)
def cnotice(self, command, text):
"""Send a CTCP notice to the recipient"""
return self.notice("\001%s %s\001" % (irc.upper(command), text))
def kick(self, text):
"""Kick the recipient off"""
pass
def mode(self, mode, addl=None):
"""Set modes on the recipient"""
pass
def write_raw(self, args, text):
"""Send raw data to the IRC server"""
return self.__interface.write(args, text)
class Channel(Recipient):
pass
class User(Recipient):
pass
class Server(Recipient):
pass
class Interface:
def __init__(self, interface):
self.__server = None
self.__empty = Recipient(NullInterface(), "")
self.__interface = interface
def connect(self, server, port, nick, gecos):
self.__server = irc.Client()
self.__server.connect(server, port, nick, gecos)
def fileno(self):
return self.__server.fileno()
def write(self, args, *text):
apply (self.__server.write, (args,) + tuple(text))
def recipient(self, name):
if name[0] in ["&", "#"]:
return Channel(self, name)
else:
return User(self, name)
def guess_forum(self, sender, args):
if args[2][0] in ("&", "#"):
return Channel(self, args[2])
else:
return sender
def handle_input(self):
while 1:
line = self.__server.get_line()
if not line:
return
op, args, text = self.__server.parse_line(line)
op, sender, recip, forum, addl = self._parse_more(op, args, text)
self.__interface.handle_message(op, sender, recip, forum, addl,
args, text)
def _parse_more(self, op, args, text):
"""Parse more, creating objects and stuff
This returns a 4-tuple:
(sender, recip, forum, addl)
The first three are Recipient objects, set up so that you don't
have to worry about whether a message was sent privately, to a
channel, or whether or not there was a recipient. For any
places where it would not make sense to have an object defined,
a Null recipient is used--you can jabber to it as much as you
like, but nothing will be sent out.
addl is another tuple, containing additional information which
might be relelvant. Here's what it will contain, based on the
server operation:
op | contents
---------|------------
PRIVMSG | Text of the message
NOTICE | Text of the notice
CPRIVMSG | CTCP command, Text of the command
CNOTICE | CTCP command, Text of the command
KICK | Text of the kick
MODE | Not sure yet
JOIN | Empty
PART | Empty
QUIT | Quit message
PING | Ping text (usually the time)
"""
try:
sender = self.recipient(irc.unpack_nuhost(args[0])[0])
except ValueError:
sender = Server(self, args[0])
recip = self.__empty
forum = self.__empty
addl = ()
if op in ("PRIVMSG", "NOTICE"):
forum = self.guess_forum(sender, args)
addl = (text,)
elif op in ("CPRIVMSG", "CNOTICE"):
forum = self.guess_forum(sender, args)
splits = string.split(text, " ")
if splits[0] == "DCC":
op = "DC" + op
addl = (splits[1],) + tuple(splits[2:])
else:
addl = (splits[0],) + tuple(splits[1:])
elif op in ("KICK",):
recip = self.recipient(args[3])
forum = self.recipient(args[2])
addl = (text,)
elif op in ("MODE",):
forum = self.recipient(args[2])
addl = args[3:]
elif op in ("JOIN", "PART"):
forum = self.recipient(text)
elif op in ("QUIT",):
addl = (text,)
elif op in ("PING",):
addl = (text,)
else:
try:
int(op)
except ValueError:
print "WARNING: can't parse_more:", op
if forum == self.__empty:
forum = Server(self, args[0])
return (op, sender, recip, forum, addl)
class NullInterface(Interface):
"""Null Interface stub class for empty values"""
def __init__(self):
pass
def connect(self, *ignored):
pass
def fileno(self):
raise AttributeError, "filenumber requested on null interface"
def write(self, *ignored):
pass
def handle_input(self):
pass