def recv(self, timeout=None):
        """
        High-level IRC buffering system and processor.
        Optional arguments:
        * timeout=None - Time to wait before returning None.
            Defaults to waiting forever.
        """
        with self.lock:
            if timeout != None:
                if self.readable(timeout) == False:
                    return None
            data = self._raw_recv()
            segments = data.split()

            if segments[1] == 'JOIN':
                who = self._from_(segments[0][1:])
                channel = segments[2][1:]
                if channel not in self.channels:
                    self.stepback(append=False)
                    return 'JOIN', self.join_(channel, process_only=True)
                else:
                    self.channels[channel]['USERS'][who[0]] = \
                    ['', '', '', '', '']
                return 'JOIN', (who, channel)

            elif segments[1] == 'PART':
                who = self._from_(segments[0].replace(':', '', 1))
                channel = segments[2]
                del self.channels[channel]['USERS'][who[0]]
                try:
                    reason = ' '.join(segments[3:]).replace(':', '', 1)
                    return 'PART', (who, channel, reason)
                except IndexError:
                    who = self._from_(segments[0].replace(':', '', 1))
                    return 'PART', (who, channel, '')

            elif segments[1] == 'PRIVMSG':
                who = self._from_(segments[0].replace(':', '', 1))
                msg = ' '.join(segments[3:]).replace(':', '', 1)
                rvalue = 'PRIVMSG', (who, segments[2], msg)

                if msg.find('\001') == 0:
                    rctcp = self.ctcp_decode(msg)
                    return 'CTCP', (rvalue[1][0], rvalue[1][1], rctcp)
                else:
                    return rvalue

            elif segments[1] == 'NOTICE':
                who = self._from_(segments[0].replace(':', '', 1))
                msg = ' '.join(segments[3:]).replace(':', '', 1)
                if msg.find('\001') == 0:
                    msg = self.ctcp_decode(msg)
                    return 'CTCP_REPLY', (who, segments[2], msg)
                return 'NOTICE', (who, segments[2], msg)

            elif segments[1] == 'MODE':
                mode = ' '.join(segments[3:]).replace(':', '', 1)
                who = self._from_(segments[0][1:])
                target = segments[2]
                if target != self.current_nick:
                    self.parse_cmode_string(mode, target)
                    return 'MODE', (who, segments[2], mode)
                else:
                    return 'MODE', (who, mode.replace(':', '', 1))

            elif segments[1] == 'KICK':
                who = self._from_(segments[0].replace(':', '', 1))
                if self.current_nick == segments[3]:
                    del self.channels[segments[2]]
                else:
                    del self.channels[segments[2]]['USERS'][segments[3]]
                reason = ' '.join(segments[4:]).replace(':', '', 1)
                return 'KICK', (who, segments[2], segments[3], reason)

            elif segments[1] == 'INVITE':
                who = self._from_(segments[0].replace(':', '', 1))
                channel = segments[3].replace(':', '', 1)
                return 'INVITE', (who, segments[2], channel)

            elif segments[1] == 'NICK':
                who = self._from_(segments[0].replace(':', '', 1))
                new_nick = ' '.join(segments[2:]).replace(':', '', 1)
                if self.current_nick == who[0]:
                    self.current_nick = new_nick
                for channel in self.channels:
                    if who[0] in self.channels[channel]['USERS']:
                        priv_level = self.channels[channel]['USERS'][who[0]]
                        del self.channels[channel]['USERS'][who[0]]
                        self.channels[channel]['USERS'][new_nick] = priv_level
                return 'NICK', (who, new_nick)

            elif segments[1] == 'TOPIC':
                who = self._from_(segments[0].replace(':', '', 1))
                channel = segments[2]
                topic = ' '.join(segments[3:]).replace(':', '', 1)
                self.channels[channel]['TOPIC'] = topic
                return 'TOPIC', (who, channel, topic)

            elif segments[1] == 'QUIT':
                who = self._from_(segments[0].replace(':', '', 1))
                msg = ' '.join(segments[2:]).replace(':', '', 1)
                for channel in self.channels:
                    if who[0] in self.channels[channel]['USERS']:
                        del self.channels[channel]['USERS'][who[0]]
                return 'QUIT', (who, msg)

            elif segments[1] == '250':
                self.lusers['HIGHESTCONNECTIONS'] = segments[6]
                self.lusers['TOTALCONNECTIONS'] = segments[9][1:]
                return 'LUSERS', self.lusers

            elif segments[1] == '251':
                self.lusers['USERS'] = segments[5]
                self.lusers['INVISIBLE'] = segments[8]
                self.lusers['SERVERS'] = segments[11]
                return 'LUSERS', self.lusers

            elif segments[1] == '252':
                self.lusers['OPERATORS'] = segments[3]
                return 'LUSERS', self.lusers

            elif segments[1] == '253':
                self.lusers['UNKNOWN'] = segments[3]
                return 'LUSERS', self.lusers

            elif segments[1] == '254':
                self.lusers['CHANNELS'] = segments[3]
                return 'LUSERS', self.lusers

            elif segments[1] == '255':
                self.lusers['CLIENTS'] = segments[5]
                self.lusers['LSERVERS'] = segments[8]
                return 'LUSERS', self.lusers

            elif segments[1] == '265':
                self.lusers['LOCALUSERS'] = segments[6]
                self.lusers['LOCALMAX'] = segments[8]
                return 'LUSERS', self.lusers

            elif segments[1] == '266':
                self.lusers['GLOBALUSERS'] = segments[6]
                self.lusers['GLOBALMAX'] = segments[8]
                return 'LUSERS', self.lusers

            elif segments[0] == 'ERROR':
                self.quit()
                return 'ERROR', ' '.join(segments[1:]).replace(':', '', 1)
            else:
                self.stepback(append=False)
                return 'UNKNOWN', self._recv(rm_first=False)
def recv ( self , timeout = None ) : with self . lock : if timeout != None : if self . readable ( timeout ) == False : return None data = self . _raw_recv ( ) segments = data . split ( ) if segments [ 1 ] == 'JOIN' : who = self . _from_ ( segments [ 0 ] [ 1 : ] ) channel = segments [ 2 ] [ 1 : ] if channel not in self . channels : self . stepback ( append = False ) return 'JOIN' , self . join_ ( channel , process_only = True ) else : self . channels [ channel ] [ 'USERS' ] [ who [ 0 ] ] = [ '' , '' , '' , '' , '' ] return 'JOIN' , ( who , channel ) elif segments [ 1 ] == 'PART' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) channel = segments [ 2 ] del self . channels [ channel ] [ 'USERS' ] [ who [ 0 ] ] try : reason = ' ' . join ( segments [ 3 : ] ) . replace ( ':' , '' , 1 ) return 'PART' , ( who , channel , reason ) except IndexError : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) return 'PART' , ( who , channel , '' ) elif segments [ 1 ] == 'PRIVMSG' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) msg = ' ' . join ( segments [ 3 : ] ) . replace ( ':' , '' , 1 ) rvalue = 'PRIVMSG' , ( who , segments [ 2 ] , msg ) if msg . find ( '\001' ) == 0 : rctcp = self . ctcp_decode ( msg ) return 'CTCP' , ( rvalue [ 1 ] [ 0 ] , rvalue [ 1 ] [ 1 ] , rctcp ) else : return rvalue elif segments [ 1 ] == 'NOTICE' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) msg = ' ' . join ( segments [ 3 : ] ) . replace ( ':' , '' , 1 ) if msg . find ( '\001' ) == 0 : msg = self . ctcp_decode ( msg ) return 'CTCP_REPLY' , ( who , segments [ 2 ] , msg ) return 'NOTICE' , ( who , segments [ 2 ] , msg ) elif segments [ 1 ] == 'MODE' : mode = ' ' . join ( segments [ 3 : ] ) . replace ( ':' , '' , 1 ) who = self . _from_ ( segments [ 0 ] [ 1 : ] ) target = segments [ 2 ] if target != self . current_nick : self . parse_cmode_string ( mode , target ) return 'MODE' , ( who , segments [ 2 ] , mode ) else : return 'MODE' , ( who , mode . replace ( ':' , '' , 1 ) ) elif segments [ 1 ] == 'KICK' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) if self . current_nick == segments [ 3 ] : del self . channels [ segments [ 2 ] ] else : del self . channels [ segments [ 2 ] ] [ 'USERS' ] [ segments [ 3 ] ] reason = ' ' . join ( segments [ 4 : ] ) . replace ( ':' , '' , 1 ) return 'KICK' , ( who , segments [ 2 ] , segments [ 3 ] , reason ) elif segments [ 1 ] == 'INVITE' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) channel = segments [ 3 ] . replace ( ':' , '' , 1 ) return 'INVITE' , ( who , segments [ 2 ] , channel ) elif segments [ 1 ] == 'NICK' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) new_nick = ' ' . join ( segments [ 2 : ] ) . replace ( ':' , '' , 1 ) if self . current_nick == who [ 0 ] : self . current_nick = new_nick for channel in self . channels : if who [ 0 ] in self . channels [ channel ] [ 'USERS' ] : priv_level = self . channels [ channel ] [ 'USERS' ] [ who [ 0 ] ] del self . channels [ channel ] [ 'USERS' ] [ who [ 0 ] ] self . channels [ channel ] [ 'USERS' ] [ new_nick ] = priv_level return 'NICK' , ( who , new_nick ) elif segments [ 1 ] == 'TOPIC' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) channel = segments [ 2 ] topic = ' ' . join ( segments [ 3 : ] ) . replace ( ':' , '' , 1 ) self . channels [ channel ] [ 'TOPIC' ] = topic return 'TOPIC' , ( who , channel , topic ) elif segments [ 1 ] == 'QUIT' : who = self . _from_ ( segments [ 0 ] . replace ( ':' , '' , 1 ) ) msg = ' ' . join ( segments [ 2 : ] ) . replace ( ':' , '' , 1 ) for channel in self . channels : if who [ 0 ] in self . channels [ channel ] [ 'USERS' ] : del self . channels [ channel ] [ 'USERS' ] [ who [ 0 ] ] return 'QUIT' , ( who , msg ) elif segments [ 1 ] == '250' : self . lusers [ 'HIGHESTCONNECTIONS' ] = segments [ 6 ] self . lusers [ 'TOTALCONNECTIONS' ] = segments [ 9 ] [ 1 : ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '251' : self . lusers [ 'USERS' ] = segments [ 5 ] self . lusers [ 'INVISIBLE' ] = segments [ 8 ] self . lusers [ 'SERVERS' ] = segments [ 11 ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '252' : self . lusers [ 'OPERATORS' ] = segments [ 3 ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '253' : self . lusers [ 'UNKNOWN' ] = segments [ 3 ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '254' : self . lusers [ 'CHANNELS' ] = segments [ 3 ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '255' : self . lusers [ 'CLIENTS' ] = segments [ 5 ] self . lusers [ 'LSERVERS' ] = segments [ 8 ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '265' : self . lusers [ 'LOCALUSERS' ] = segments [ 6 ] self . lusers [ 'LOCALMAX' ] = segments [ 8 ] return 'LUSERS' , self . lusers elif segments [ 1 ] == '266' : self . lusers [ 'GLOBALUSERS' ] = segments [ 6 ] self . lusers [ 'GLOBALMAX' ] = segments [ 8 ] return 'LUSERS' , self . lusers elif segments [ 0 ] == 'ERROR' : self . quit ( ) return 'ERROR' , ' ' . join ( segments [ 1 : ] ) . replace ( ':' , '' , 1 ) else : self . stepback ( append = False ) return 'UNKNOWN' , self . _recv ( rm_first = False )
High-level IRC buffering system and processor.
        Optional arguments:
        * timeout=None - Time to wait before returning None.
            Defaults to waiting forever.