<s> import socket <EOL> import threading <EOL> import re <EOL> import time <EOL> class ircOutputBuffer : <EOL> def __init__ ( self , irc ) : <EOL> self . waiting = False <EOL> self . irc = irc <EOL> self . queue = [ ] <EOL> self . error = False <EOL> def __pop ( self ) : <EOL> if len ( self . queue ) == <NUM_LIT:0> : <EOL> self . waiting = False <EOL> else : <EOL> self . sendImmediately ( self . queue [ <NUM_LIT:0> ] ) <EOL> self . queue = self . queue [ <NUM_LIT:1> : ] <EOL> self . __startPopTimer ( ) <EOL> def __startPopTimer ( self ) : <EOL> self . timer = threading . Timer ( <NUM_LIT:1> , self . __pop ) <EOL> self . timer . start ( ) <EOL> def sendBuffered ( self , string ) : <EOL> if self . waiting : <EOL> self . queue . append ( string ) <EOL> else : <EOL> self . waiting = True <EOL> self . sendImmediately ( string ) <EOL> self . __startPopTimer ( ) <EOL> def sendImmediately ( self , string ) : <EOL> if not self . error : <EOL> try : <EOL> self . irc . send ( bytes ( string ) + b"<STR_LIT:\r\n>" ) <EOL> except socket . error , msg : <EOL> self . error = True <EOL> print "<STR_LIT>" , msg <EOL> print "<STR_LIT>" + string + "<STR_LIT>" <EOL> def isInError ( self ) : <EOL> return self . error <EOL> class ircInputBuffer : <EOL> def __init__ ( self , irc ) : <EOL> self . buffer = "<STR_LIT>" <EOL> self . irc = irc <EOL> self . lines = [ ] <EOL> def __recv ( self ) : <EOL> try : <EOL> data = self . buffer + self . irc . recv ( <NUM_LIT> ) <EOL> except socket . error , msg : <EOL> raise socket . error , msg <EOL> self . lines += data . split ( b"<STR_LIT:\r\n>" ) <EOL> self . buffer = self . lines [ len ( self . lines ) - <NUM_LIT:1> ] <EOL> self . lines = self . lines [ : len ( self . lines ) - <NUM_LIT:1> ] <EOL> def getLine ( self ) : <EOL> while len ( self . lines ) == <NUM_LIT:0> : <EOL> try : <EOL> self . __recv ( ) <EOL> except socket . error , msg : <EOL> raise socket . error , msg <EOL> time . sleep ( <NUM_LIT:1> ) ; <EOL> line = self . lines [ <NUM_LIT:0> ] <EOL> self . lines = self . lines [ <NUM_LIT:1> : ] <EOL> return str ( line ) <EOL> class ircBot ( threading . Thread ) : <EOL> def __init__ ( self , network , port , name , description ) : <EOL> threading . Thread . __init__ ( self ) <EOL> self . keepGoing = True <EOL> self . name = name <EOL> self . desc = description <EOL> self . network = network <EOL> self . port = port <EOL> self . identifyNickCommands = [ ] <EOL> self . identifyLock = False <EOL> self . binds = [ ] <EOL> self . debug = False <EOL> def __identAccept ( self , nick ) : <EOL> """<STR_LIT>""" <EOL> i = <NUM_LIT:0> <EOL> while i < len ( self . identifyNickCommands ) : <EOL> ( nickName , accept , acceptParams , reject , rejectParams ) = self . identifyNickCommands [ i ] <EOL> if nick == nickName : <EOL> accept ( * acceptParams ) <EOL> self . identifyNickCommands . pop ( i ) <EOL> else : <EOL> i += <NUM_LIT:1> <EOL> def __identReject ( self , nick ) : <EOL> i = <NUM_LIT:0> <EOL> while i < len ( self . identifyNickCommands ) : <EOL> ( nickName , accept , acceptParams , reject , rejectParams ) = self . identifyNickCommands [ i ] <EOL> if nick == nickName : <EOL> reject ( * rejectParams ) <EOL> self . identifyNickCommands . pop ( i ) <EOL> else : <EOL> i += <NUM_LIT:1> <EOL> def __callBind ( self , msgtype , sender , headers , message ) : <EOL> for ( messageType , callback ) in self . binds : <EOL> if ( messageType == msgtype ) : <EOL> callback ( sender , headers , message ) <EOL> def __processLine ( self , line ) : <EOL> if "<STR_LIT:@>" in line : <EOL> at = line . find ( "<STR_LIT:@>" ) <EOL> gap = line [ at : ] . find ( "<STR_LIT:U+0020>" ) + at + <NUM_LIT:1> <EOL> lastColon = line [ gap + <NUM_LIT:1> : ] . find ( "<STR_LIT::>" ) + <NUM_LIT:2> + gap <EOL> else : <EOL> lastColon = line [ <NUM_LIT:1> : ] . find ( "<STR_LIT::>" ) + <NUM_LIT:1> <EOL> if "<STR_LIT::>" not in line [ <NUM_LIT:1> : ] : <EOL> headers = line [ <NUM_LIT:1> : ] . strip ( ) . split ( "<STR_LIT:U+0020>" ) <EOL> message = "<STR_LIT>" <EOL> else : <EOL> headers = line [ <NUM_LIT:1> : lastColon - <NUM_LIT:1> ] . strip ( ) . split ( "<STR_LIT:U+0020>" ) <EOL> message = line [ lastColon : ] <EOL> sender = headers [ <NUM_LIT:0> ] <EOL> if len ( headers ) < <NUM_LIT:2> : <EOL> self . __debugPrint ( "<STR_LIT>" + line + "<STR_LIT>" ) <EOL> else : <EOL> if "<STR_LIT:!>" in sender : <EOL> cut = headers [ <NUM_LIT:0> ] . find ( '<STR_LIT:!>' ) <EOL> if cut != - <NUM_LIT:1> : <EOL> sender = sender [ : cut ] <EOL> msgtype = headers [ <NUM_LIT:1> ] <EOL> if msgtype == "<STR_LIT>" and message . startswith ( "<STR_LIT>" ) and message . endswith ( "<STR_LIT>" ) : <EOL> msgtype = "<STR_LIT>" <EOL> message = message [ <NUM_LIT:8> : - <NUM_LIT:1> ] <EOL> self . __callBind ( msgtype , sender , headers [ <NUM_LIT:2> : ] , message ) <EOL> else : <EOL> self . __debugPrint ( "<STR_LIT:[>" + headers [ <NUM_LIT:1> ] + "<STR_LIT>" + message ) <EOL> if ( headers [ <NUM_LIT:1> ] == "<STR_LIT>" or headers [ <NUM_LIT:1> ] == "<STR_LIT>" ) and len ( headers ) >= <NUM_LIT:4> : <EOL> self . __identAccept ( headers [ <NUM_LIT:3> ] ) <EOL> if headers [ <NUM_LIT:1> ] == "<STR_LIT>" and len ( headers ) >= <NUM_LIT:4> : <EOL> self . __identReject ( headers [ <NUM_LIT:3> ] ) <EOL> if len ( self . identifyNickCommands ) == <NUM_LIT:0> : <EOL> self . identifyLock = False <EOL> else : <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + self . identifyNickCommands [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ) <EOL> self . __callBind ( headers [ <NUM_LIT:1> ] , sender , headers [ <NUM_LIT:2> : ] , message ) <EOL> def __debugPrint ( self , s ) : <EOL> if self . debug : <EOL> print s <EOL> def ban ( self , banMask , channel , reason ) : <EOL> self . __debugPrint ( "<STR_LIT>" + banMask + "<STR_LIT>" ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + channel + "<STR_LIT:U+0020>" + banMask ) <EOL> self . kick ( nick , channel , reason ) <EOL> def bind ( self , msgtype , callback ) : <EOL> for i in xrange ( <NUM_LIT:0> , len ( self . binds ) ) : <EOL> if self . binds [ i ] [ <NUM_LIT:0> ] == msgtype : <EOL> self . binds . remove ( i ) <EOL> self . binds . append ( ( msgtype , callback ) ) <EOL> def connect ( self ) : <EOL> self . __debugPrint ( "<STR_LIT>" ) <EOL> self . irc = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> self . irc . connect ( ( self . network , self . port ) ) <EOL> self . inBuf = ircInputBuffer ( self . irc ) <EOL> self . outBuf = ircOutputBuffer ( self . irc ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + self . name ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + self . name + "<STR_LIT:U+0020>" + self . name + "<STR_LIT:U+0020>" + self . name + "<STR_LIT>" + self . desc ) <EOL> def debugging ( self , state ) : <EOL> self . debug = state <EOL> def disconnect ( self , qMessage ) : <EOL> self . __debugPrint ( "<STR_LIT>" ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + qMessage ) <EOL> self . irc . close ( ) <EOL> def identify ( self , nick , approvedFunc , approvedParams , deniedFunc , deniedParams ) : <EOL> self . __debugPrint ( "<STR_LIT>" + nick + "<STR_LIT>" ) <EOL> self . identifyNickCommands += [ ( nick , approvedFunc , approvedParams , deniedFunc , deniedParams ) ] <EOL> if not self . identifyLock : <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + nick ) <EOL> self . identifyLock = True <EOL> def joinchan ( self , channel ) : <EOL> self . __debugPrint ( "<STR_LIT>" + channel + "<STR_LIT>" ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + channel ) <EOL> def kick ( self , nick , channel , reason ) : <EOL> self . __debugPrint ( "<STR_LIT>" + nick + "<STR_LIT>" ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + channel + "<STR_LIT:U+0020>" + nick + "<STR_LIT>" + reason ) <EOL> def reconnect ( self ) : <EOL> self . disconnect ( "<STR_LIT>" ) <EOL> self . __debugPrint ( "<STR_LIT>" ) <EOL> time . sleep ( <NUM_LIT:5> ) <EOL> self . connect ( ) <EOL> def run ( self ) : <EOL> self . __debugPrint ( "<STR_LIT>" ) <EOL> self . connect ( ) <EOL> while self . keepGoing : <EOL> line = "<STR_LIT>" <EOL> while len ( line ) == <NUM_LIT:0> : <EOL> try : <EOL> line = self . inBuf . getLine ( ) <EOL> except socket . error , msg : <EOL> print "<STR_LIT>" , msg <EOL> self . reconnect ( ) <EOL> if line . startswith ( "<STR_LIT>" ) : <EOL> self . outBuf . sendImmediately ( "<STR_LIT>" + line . split ( ) [ <NUM_LIT:1> ] ) <EOL> else : <EOL> self . __processLine ( line ) <EOL> if self . outBuf . isInError ( ) : <EOL> self . reconnect ( ) <EOL> def say ( self , recipient , message ) : <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + recipient + "<STR_LIT>" + message ) <EOL> def send ( self , string ) : <EOL> self . outBuf . sendBuffered ( string ) <EOL> def stop ( self ) : <EOL> self . keepGoing = False <EOL> def unban ( self , banMask , channel ) : <EOL> self . __debugPrint ( "<STR_LIT>" + banMask + "<STR_LIT>" ) <EOL> self . outBuf . sendBuffered ( "<STR_LIT>" + channel + "<STR_LIT:U+0020>" + banMask ) </s>
