Remove evil tabs

This commit is contained in:
Neale Pickett 2010-03-16 15:19:50 -06:00
parent 09e9796758
commit 201558ca14
1 changed files with 150 additions and 150 deletions

298
irc.py
View File

@ -38,8 +38,8 @@ class IRCHandler(asynchat.async_chat):
self.connect(host)
def handle_connect(self):
self.write(['NICK', self.nick])
self.write(['USER', self.nick, '+iw', self.nick], self.gecos)
self.write(['NICK', self.nick])
self.write(['USER', self.nick, '+iw', self.nick], self.gecos)
def connect(self, host):
self.waiting = False
@ -90,55 +90,55 @@ class IRCHandler(asynchat.async_chat):
self.parse_line(line)
def write(self, args, *text):
"""Send out an IRC command
"""Send out an IRC command
This function helps to prevent you from shooting yourself in the
foot, by forcing you to send commands that are in a valid format
(although it doesn't check the validity of the actual commands).
This function helps to prevent you from shooting yourself in the
foot, by forcing you to send commands that are in a valid format
(although it doesn't check the validity of the actual commands).
As we all know, IRC commands take the form
As we all know, IRC commands take the form
:COMMAND ARG1 ARG2 ARG3 ... :text string
:COMMAND ARG1 ARG2 ARG3 ... :text string
where 'text string' is optional. Well, that's exactly how this
function works. Args is a list of length at least one, and text
string can be any number of strings. You can call the function
like this:
where 'text string' is optional. Well, that's exactly how this
function works. Args is a list of length at least one, and text
string can be any number of strings. You can call the function
like this:
write(['PRIVMSG', nick], 'Hello 12')
write(['PRIVMSG', nick], 'Hello 12')
or like this:
or like this:
write(['PRIVMSG', nick], 'Hello', '12')
write(['PRIVMSG', nick], 'Hello', '12')
or even like this:
write(['PRIVMSG', nick], 'Hello', 12)
write(['PRIVMSG', nick], 'Hello', 12)
And you'll get the same result with all three.
And you'll get the same result with all three.
"""
"""
if (type(args) == types.StringType):
cmd = args
else:
cmd = u' '.join(args)
cmdstr = cmd
if (text):
txt = ''
for t in (text):
if type(t) in (types.StringType, types.UnicodeType):
txt = txt + ' ' + t
elif type(t) in (types.ListType, types.TupleType):
for i in (t):
try:
txt = ' '.join([txt, i])
except TypeError:
txt = ' '.join([txt, repr(i)])
else:
txt = ' '.join([txt, repr(t)])
txt = txt[1:]
cmdstr = "%s :%s" % (cmdstr, txt)
if (type(args) == types.StringType):
cmd = args
else:
cmd = u' '.join(args)
cmdstr = cmd
if (text):
txt = ''
for t in (text):
if type(t) in (types.StringType, types.UnicodeType):
txt = txt + ' ' + t
elif type(t) in (types.ListType, types.TupleType):
for i in (t):
try:
txt = ' '.join([txt, i])
except TypeError:
txt = ' '.join([txt, repr(i)])
else:
txt = ' '.join([txt, repr(t)])
txt = txt[1:]
cmdstr = "%s :%s" % (cmdstr, txt)
encstr = cmdstr.encode('utf8', 'replace')
self.dbg("-> %s " % encstr)
try:
@ -148,81 +148,81 @@ class IRCHandler(asynchat.async_chat):
def parse_line(self, line):
"""Parse a server-provided line
"""Parse a server-provided line
This does all the magic of parsing those ill-formatted IRC
messages. It will also decide if a PRIVMSG or NOTICE is using
CTCP (the client-to-client protocol, which by convention is any
of the above messages with ^A on both ends of the text.
This does all the magic of parsing those ill-formatted IRC
messages. It will also decide if a PRIVMSG or NOTICE is using
CTCP (the client-to-client protocol, which by convention is any
of the above messages with ^A on both ends of the text.
This function goes on to invoke self.eval_triggers on the parsed
data like this:
This function goes on to invoke self.eval_triggers on the parsed
data like this:
self.eval_triggers(operation, arguments, text)
self.eval_triggers(operation, arguments, text)
where operation and text are strings, and arguments is a list.
where operation and text are strings, and arguments is a list.
It returns the same tuple (op, args, text).
It returns the same tuple (op, args, text).
"""
"""
line = line.decode('utf8', 'replace')
if (line[0] == ':'):
with_uname = 1
line = line [1:]
else:
with_uname = 0
try:
[args, text] = line.split(' :', 1)
args = args.split()
except ValueError:
args = line.split()
text = ''
if (with_uname != 1):
op = args[0]
elif ((args[1] in ["PRIVMSG", "NOTICE"]) and
(text and (text[0] == '\001') and (text[-1] == '\001'))):
op = "C" + args[1]
text = text[1:-1]
else:
op = args[1]
if (line[0] == ':'):
with_uname = 1
line = line [1:]
else:
with_uname = 0
try:
[args, text] = line.split(' :', 1)
args = args.split()
except ValueError:
args = line.split()
text = ''
if (with_uname != 1):
op = args[0]
elif ((args[1] in ["PRIVMSG", "NOTICE"]) and
(text and (text[0] == '\001') and (text[-1] == '\001'))):
op = "C" + args[1]
text = text[1:-1]
else:
op = args[1]
self.dbg("<- %s %s %s" % (op, args, text))
self.handle(op, args, text)
return (op, args, text)
self.handle(op, args, text)
return (op, args, text)
def handle(self, op, args, text):
"""Take action on a server message
"""Take action on a server message
Right now, just invokes
Right now, just invokes
self.do_[op](args, text)
self.do_[op](args, text)
where [op] is the operation passed in.
where [op] is the operation passed in.
This is a good method to overload if you want a really advanced
client supporting bindings.
This is a good method to overload if you want a really advanced
client supporting bindings.
"""
try:
method = getattr(self, "do_" + lower(op))
except AttributeError:
"""
try:
method = getattr(self, "do_" + lower(op))
except AttributeError:
self.dbg("Unhandled: %s" % (op, args, text))
return
method(args, text)
method(args, text)
class Recipient:
"""Abstract recipient object"""
def __init__(self, interface, name):
self._interface = interface
self._name = name
self._interface = interface
self._name = name
def __repr__(self):
return 'Recipient(%s)' % self.name()
def name(self):
return self._name
return self._name
def is_channel(self):
return False
@ -238,29 +238,29 @@ class Recipient:
self.write([cmd, self._name], text)
def msg(self, text):
"""Tell the recipient something"""
"""Tell the recipient something"""
self.cmd("PRIVMSG", text)
self.cmd("PRIVMSG", text)
def notice(self, text):
"""Send a notice to the recipient"""
"""Send a notice to the recipient"""
self.cmd("NOTICE", text)
self.cmd("NOTICE", text)
def ctcp(self, command, text):
"""Send a CTCP command to the recipient"""
"""Send a CTCP command to the recipient"""
return self.msg("\001%s %s\001" % (upper(command), text))
return self.msg("\001%s %s\001" % (upper(command), text))
def act(self, text):
"""Send an action to the recipient"""
"""Send an action to the recipient"""
return self.ctcp("ACTION", text)
return self.ctcp("ACTION", text)
def cnotice(self, command, text):
"""Send a CTCP notice to the recipient"""
"""Send a CTCP notice to the recipient"""
return self.notice("\001%s %s\001" % (upper(command), text))
return self.notice("\001%s %s\001" % (upper(command), text))
class Channel(Recipient):
def __repr__(self):
@ -281,9 +281,9 @@ class User(Recipient):
def recipient(interface, name):
if name[0] in ["&", "#"]:
return Channel(interface, name)
return Channel(interface, name)
else:
return User(interface, name, None, None)
return User(interface, name, None, None)
class SmartIRCHandler(IRCHandler):
"""This is like the IRCHandler, except it creates Recipient objects
@ -300,7 +300,7 @@ class SmartIRCHandler(IRCHandler):
traceback.print_exception(*exception)
def handle(self, op, args, text):
"""Parse more, creating objects and stuff
"""Parse more, creating objects and stuff
makes a call to self.handle_op(sender, forum, addl)
@ -314,22 +314,22 @@ class SmartIRCHandler(IRCHandler):
always send a reply to forum, and it will be sent back in an
appropriate manner (ie. the way you expect).
addl is a tuple, containing additional information which might
be relelvant. Here's what it will contain, based on the server
operation:
addl is a tuple, containing additional information which might
be relelvant. Here's what it will contain, based on the server
operation:
op | addl
---------+----------------
PRIVMSG | text of the message
NOTICE | text of the notice
CPRIVMSG | CTCP command, text of the command
CNOTICE | CTCP response, text of the response
KICK * | victim of kick, kick text
MODE * | all mode args
JOIN * | empty
PART * | empty
QUIT | quit message
PING | ping text
---------+----------------
PRIVMSG | text of the message
NOTICE | text of the notice
CPRIVMSG | CTCP command, text of the command
CNOTICE | CTCP response, text of the response
KICK * | victim of kick, kick text
MODE * | all mode args
JOIN * | empty
PART * | empty
QUIT | quit message
PING | ping text
NICK ! | old nickname
others | all arguments; text is last element
@ -338,16 +338,16 @@ class SmartIRCHandler(IRCHandler):
! The sender for the NICK command is the *new* nickname. This
is so you can send messages to the sender object and they'll
go to the right place.
"""
"""
try:
try:
sender = User(self, *unpack_nuhost(args))
except ValueError:
sender = None
forum = None
addl = ()
except ValueError:
sender = None
forum = None
addl = ()
if op in ("PRIVMSG", "NOTICE"):
if op in ("PRIVMSG", "NOTICE"):
# PRIVMSG ['neale!~user@127.0.0.1', 'PRIVMSG', '#hydra'] firebot, foo
# PRIVMSG ['neale!~user@127.0.0.1', 'PRIVMSG', 'firebot'] firebot, foo
try:
@ -358,31 +358,31 @@ class SmartIRCHandler(IRCHandler):
addl = (text,)
except IndexError:
addl = (text, args[1])
elif op in ("CPRIVMSG", "CNOTICE"):
forum = self.recipient(args[2])
splits = text.split(" ")
if splits[0] == "DCC":
op = "DC" + op
addl = (splits[1],) + tuple(splits[2:])
else:
addl = (splits[0],) + tuple(splits[1:])
elif op in ("KICK",):
forum = self.recipient(args[2])
addl = (self.recipient(args[3]), text)
elif op in ("MODE",):
forum = self.recipient(args[2])
addl = args[3:]
elif op in ("JOIN", "PART"):
elif op in ("CPRIVMSG", "CNOTICE"):
forum = self.recipient(args[2])
splits = text.split(" ")
if splits[0] == "DCC":
op = "DC" + op
addl = (splits[1],) + tuple(splits[2:])
else:
addl = (splits[0],) + tuple(splits[1:])
elif op in ("KICK",):
forum = self.recipient(args[2])
addl = (self.recipient(args[3]), text)
elif op in ("MODE",):
forum = self.recipient(args[2])
addl = args[3:]
elif op in ("JOIN", "PART"):
try:
forum = self.recipient(args[2])
except IndexError:
forum = self.recipient(text)
elif op in ("QUIT",):
addl = (text,)
elif op in ("PING", "PONG"):
elif op in ("QUIT",):
addl = (text,)
elif op in ("PING", "PONG"):
# PING ['PING'] us.boogernet.org.
# PONG ['irc.foonet.com', 'PONG', 'irc.foonet.com'] 1114199424
addl = (text,)
addl = (text,)
elif op in ("NICK",):
# NICK ['brad!~brad@10.168.2.33', 'NICK'] bradaway
#
@ -403,10 +403,10 @@ class SmartIRCHandler(IRCHandler):
forum = self.recipient(args[3])
else:
forum = self.recipient(text)
else:
try:
int(op)
except ValueError:
else:
try:
int(op)
except ValueError:
self.dbg("WARNING: unknown server code: %s" % op)
addl = tuple(args[3:]) + (text,)
@ -508,10 +508,10 @@ class Bot(SmartIRCHandler):
def close(self, final=False):
SmartIRCHandler.close(self)
if not final:
self.dbg("Connection closed, reconnecting...")
self.waiting = True
self.connected = 0
# Wait a bit and reconnect
self.dbg("Connection closed, reconnecting...")
self.waiting = True
self.connected = 0
# Wait a bit and reconnect
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.add_timer(23, lambda : self.connect(self.host))
@ -530,7 +530,7 @@ lcletters = "abcdefghijklmnopqrstuvwxyz{}|"
ultrans = string.maketrans(ucletters, lcletters)
lutrans = string.maketrans(lcletters, ucletters)
casetrans = string.maketrans(''.join([ucletters, lcletters]),
''.join([lcletters, ucletters]))
''.join([lcletters, ucletters]))
def upper(s):
"""Convert a string to upper case.
@ -590,10 +590,10 @@ def unpack_nuhost(nuhost):
"""
try:
[nick, uhost] = string.split(nuhost[0], '!', 1)
[user, host] = string.split(uhost, '@', 1)
[nick, uhost] = string.split(nuhost[0], '!', 1)
[user, host] = string.split(uhost, '@', 1)
except ValueError:
raise ValueError, "not in nick!user@host format"
raise ValueError, "not in nick!user@host format"
return (nick, user, host)
def run_forever(timeout=2.0):