<s> import os <EOL> import traceback <EOL> from twisted . words . protocols import irc <EOL> from twisted . internet import protocol , ssl <EOL> from twisted . application import internet <EOL> from twisted . web import resource <EOL> from harold . dispatcher import Dispatcher <EOL> from harold . plugins . http import ProtectedResource <EOL> from harold . plugin import Plugin <EOL> from harold . conf import PluginConfig , Option , tup <EOL> class IrcConfig ( PluginConfig ) : <EOL> username = Option ( str , default = None ) <EOL> nick = Option ( str ) <EOL> password = Option ( str , default = None ) <EOL> host = Option ( str ) <EOL> port = Option ( int , default = <NUM_LIT> ) <EOL> use_ssl = Option ( bool , default = False ) <EOL> channels = Option ( tup , default = [ ] ) <EOL> userserv_password = Option ( str , default = None ) <EOL> heartbeat_channel = Option ( str ) <EOL> def who ( irc , sender , channel , * args ) : <EOL> irc . describe ( channel , "<STR_LIT>" ) <EOL> def debug ( irc , sender , channel , * args ) : <EOL> irc . describe ( channel , "<STR_LIT>" % os . environ . get ( "<STR_LIT:name>" , "<STR_LIT>" ) ) <EOL> class IRCBot ( irc . IRCClient ) : <EOL> realname = "<STR_LIT>" <EOL> lineRate = <NUM_LIT:1> <EOL> heartbeatInterval = <NUM_LIT:30> <EOL> maxOutstandingHeartbeats = <NUM_LIT:3> <EOL> def irc_PONG ( self , prefix , params ) : <EOL> print "<STR_LIT>" <EOL> self . outstanding_heartbeats = max ( self . outstanding_heartbeats - <NUM_LIT:1> , <NUM_LIT:0> ) <EOL> def startHeartbeat ( self ) : <EOL> self . outstanding_heartbeats = <NUM_LIT:0> <EOL> irc . IRCClient . startHeartbeat ( self ) <EOL> def _sendHeartbeat ( self ) : <EOL> if self . outstanding_heartbeats > self . maxOutstandingHeartbeats : <EOL> print "<STR_LIT>" <EOL> self . transport . loseConnection ( ) <EOL> return <EOL> else : <EOL> print "<STR_LIT>" % self . outstanding_heartbeats <EOL> irc . IRCClient . _sendHeartbeat ( self ) <EOL> self . outstanding_heartbeats += <NUM_LIT:1> <EOL> def signedOn ( self ) : <EOL> print "<STR_LIT>" <EOL> if self . userserv_password : <EOL> self . msg ( "<STR_LIT>" , "<STR_LIT>" % ( self . username , <EOL> self . userserv_password ) ) <EOL> for channel in self . factory . channels : <EOL> self . join ( channel ) <EOL> self . factory . dispatcher . registerConsumer ( self ) <EOL> def connectionLost ( self , * args , ** kwargs ) : <EOL> print "<STR_LIT>" <EOL> irc . IRCClient . connectionLost ( self , * args , ** kwargs ) <EOL> self . factory . dispatcher . deregisterConsumer ( self ) <EOL> def privmsg ( self , user , channel , msg ) : <EOL> sender_nick = user . partition ( '<STR_LIT:!>' ) [ <NUM_LIT:0> ] <EOL> self . factory . onMessageReceived ( sender_nick , channel , msg ) <EOL> def send_message ( self , channel , message ) : <EOL> message = unicode ( message ) <EOL> message = message . translate ( { <EOL> ord ( "<STR_LIT:\r>" ) : None , <EOL> ord ( "<STR_LIT:\n>" ) : None , <EOL> } ) <EOL> message = message [ : <NUM_LIT> ] <EOL> self . msg ( channel , message . encode ( '<STR_LIT:utf-8>' ) ) <EOL> def set_topic ( self , channel , topic ) : <EOL> self . topic ( channel , topic . encode ( '<STR_LIT:utf-8>' ) ) <EOL> class IRCBotFactory ( protocol . ClientFactory ) : <EOL> protocol = IRCBot <EOL> def __init__ ( self , plugin , config , dispatcher , channels ) : <EOL> self . plugin = plugin <EOL> self . config = config <EOL> self . dispatcher = dispatcher <EOL> self . channels = channels <EOL> def buildProtocol ( self , addr ) : <EOL> prot = protocol . ClientFactory . buildProtocol ( self , addr ) <EOL> prot . nickname = self . config . nick <EOL> prot . password = self . config . password <EOL> prot . username = self . config . username <EOL> prot . userserv_password = self . config . userserv_password <EOL> prot . heartbeat_channel = self . config . heartbeat_channel <EOL> return prot <EOL> def clientConnectionFailed ( self , connector , reason ) : <EOL> connector . connect ( ) <EOL> def clientConnectionLost ( self , connector , reason ) : <EOL> connector . connect ( ) <EOL> def onMessageReceived ( self , sender_nick , channel , msg ) : <EOL> self . plugin . onMessageReceived ( sender_nick , channel , msg ) <EOL> class MessageListener ( ProtectedResource ) : <EOL> isLeaf = True <EOL> def __init__ ( self , http , dispatcher ) : <EOL> ProtectedResource . __init__ ( self , http ) <EOL> self . dispatcher = dispatcher <EOL> def _handle_request ( self , request ) : <EOL> channel = request . args [ '<STR_LIT>' ] [ <NUM_LIT:0> ] <EOL> try : <EOL> message = unicode ( request . args [ '<STR_LIT:message>' ] [ <NUM_LIT:0> ] , '<STR_LIT:utf-8>' ) <EOL> except UnicodeDecodeError : <EOL> return <EOL> else : <EOL> self . dispatcher . send_message ( channel , message ) <EOL> class SetTopicListener ( ProtectedResource ) : <EOL> isLeaf = True <EOL> def __init__ ( self , http , dispatcher ) : <EOL> ProtectedResource . __init__ ( self , http ) <EOL> self . dispatcher = dispatcher <EOL> def _handle_request ( self , request ) : <EOL> channel = request . args [ '<STR_LIT>' ] [ <NUM_LIT:0> ] <EOL> new_topic = unicode ( request . args [ '<STR_LIT>' ] [ <NUM_LIT:0> ] , '<STR_LIT:utf-8>' ) <EOL> self . dispatcher . set_topic ( channel , new_topic ) <EOL> class ChannelManager ( object ) : <EOL> def __init__ ( self , basic_channels , bot ) : <EOL> self . bot = bot <EOL> self . channels = set ( basic_channels ) <EOL> def add ( self , channel ) : <EOL> if channel not in self . channels : <EOL> self . channels . add ( channel ) <EOL> self . bot . join ( channel ) <EOL> def __iter__ ( self ) : <EOL> return self . channels . __iter__ ( ) <EOL> class IrcPlugin ( Plugin ) : <EOL> def __init__ ( self ) : <EOL> self . commands = { } <EOL> super ( IrcPlugin , self ) . __init__ ( ) <EOL> def register_command ( self , handler ) : <EOL> self . commands [ handler . __name__ ] = handler <EOL> def onMessageReceived ( self , sender_nick , channel , msg ) : <EOL> split = msg . split ( ) <EOL> if len ( split ) >= <NUM_LIT:2> : <EOL> highlight = split [ <NUM_LIT:0> ] . lower ( ) <EOL> else : <EOL> highlight = "<STR_LIT>" <EOL> if not highlight . startswith ( self . config . nick ) : <EOL> return <EOL> command , args = ( split [ <NUM_LIT:1> ] . lower ( ) , split [ <NUM_LIT:2> : ] ) <EOL> fn = self . commands . get ( command ) <EOL> if not fn : <EOL> return <EOL> try : <EOL> fn ( self . bot , sender_nick , channel , * args ) <EOL> except : <EOL> traceback . print_exc ( ) <EOL> self . bot . describe ( channel , "<STR_LIT>" ) <EOL> def make_plugin ( config , http = None ) : <EOL> irc_config = IrcConfig ( config ) <EOL> dispatcher = Dispatcher ( ) <EOL> channel_manager = ChannelManager ( irc_config . channels , dispatcher ) <EOL> if http : <EOL> http . root . putChild ( '<STR_LIT:message>' , MessageListener ( http , dispatcher ) ) <EOL> topic_root = resource . Resource ( ) <EOL> http . root . putChild ( '<STR_LIT>' , topic_root ) <EOL> topic_root . putChild ( '<STR_LIT>' , SetTopicListener ( http , dispatcher ) ) <EOL> p = IrcPlugin ( ) <EOL> p . register_command ( who ) <EOL> p . register_command ( debug ) <EOL> irc_factory = IRCBotFactory ( p , irc_config , dispatcher , channel_manager ) <EOL> p . config = irc_config <EOL> p . bot = dispatcher <EOL> p . channels = channel_manager <EOL> if irc_config : <EOL> context_factory = ssl . ClientContextFactory ( ) <EOL> p . add_service ( internet . SSLClient ( irc_config . host , <EOL> irc_config . port , <EOL> irc_factory , <EOL> context_factory ) ) <EOL> else : <EOL> p . add_service ( internet . TCPClient ( irc_config . host , <EOL> irc_config . port , <EOL> irc_factory ) ) <EOL> return p </s>
