Skip to content

Commit

Permalink
Make IRCConnection wait for the connection to be registered before se…
Browse files Browse the repository at this point in the history
…nding commands
  • Loading branch information
runeh committed May 17, 2011
1 parent 8805f22 commit 2725e49
Showing 1 changed file with 29 additions and 7 deletions.
36 changes: 29 additions & 7 deletions irc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class IRCConnection(object):
part_re = re.compile(':(?P<nick>.*?)!\S+\s+?PART\s+#(?P<channel>[-\w]+)')
join_re = re.compile(':(?P<nick>.*?)!\S+\s+?JOIN\s+:\s*#(?P<channel>[-\w]+)')
quit_re = re.compile(':(?P<nick>.*?)!\S+\s+?QUIT\s+.*')
registered_re = re.compile(':(?P<server>.*?)\s+(?:376|422)')

# mapping for logging verbosity
verbosity_map = {
Expand All @@ -42,6 +43,8 @@ def __init__(self, server, port, nick, logfile=None, verbosity=1):
self.logfile = logfile
self.verbosity = verbosity

self._registered = False
self._out_buffer = []
self._callbacks = []
self.logger = self.get_logger('ircconnection.logger', self.logfile)

Expand All @@ -61,12 +64,18 @@ def get_logger(self, logger_name, filename):

return log

def send(self, data):
def send(self, data, force=False):
"""\
Send raw data over the wire
Send raw data over the wire if connection is registered. Otherewise,
save the data to an output buffer for transmission later on.
If the force flag is true, always send data, regardless of
registration status.
"""
self._sock_file.write('%s\r\n' % data)
self._sock_file.flush()
if self._registered or force:
self._sock_file.write('%s\r\n' % data)
self._sock_file.flush()
else:
self._out_buffer.append(data)

def connect(self):
"""\
Expand All @@ -81,14 +90,14 @@ def connect(self):

self._sock_file = self._sock.makefile()

self.send('USER %s %s bla :%s' % (self.nick, self.server, self.nick))
self.send('USER %s %s bla :%s' % (self.nick, self.server, self.nick), True)
self.logger.info('Authing as %s' % self.nick)

# send NICK command as soon as authing
self.register_nick()

def register_nick(self):
self.send('NICK %s' % self.nick)
self.send('NICK %s' % self.nick, True)

def join(self, channel):
channel = channel.lstrip('#')
Expand Down Expand Up @@ -130,6 +139,7 @@ def dispatch_patterns(self):
(self.quit_re, self.handle_quit),
(self.chanmsg_re, self.handle_channel_message),
(self.privmsg_re, self.handle_private_message),
(self.registered_re, self.handle_registered),
)

def register_callbacks(self, callbacks):
Expand All @@ -153,7 +163,19 @@ def handle_ping(self, payload):
Respond to periodic PING messages from server
"""
self.logger.info('server ping: %s' % payload)
self.send('PONG %s' % payload)
self.send('PONG %s' % payload, True)

def handle_registered(self, server):
"""\
When the connection to the server is registered, send all pending
data.
"""
if not self._registered:
self.logger.info('Registered')
self._registered = True
for data in self._out_buffer:
self.send(data)
self._out_buffer = []

def handle_part(self, nick, channel):
for pattern, callback in self._callbacks:
Expand Down

0 comments on commit 2725e49

Please sign in to comment.