<s> """<STR_LIT>""" <EOL> from time import time , ctime <EOL> from zope . interface import implements <EOL> from twisted . words import iwords , ewords <EOL> from twisted . python . components import registerAdapter <EOL> from twisted . cred import portal , credentials , error as ecred <EOL> from twisted . spread import pb <EOL> from twisted . words . protocols import irc <EOL> from twisted . internet import defer , protocol <EOL> from twisted . python import log , failure , reflect <EOL> from twisted import copyright <EOL> class Group ( object ) : <EOL> implements ( iwords . IGroup ) <EOL> def __init__ ( self , name ) : <EOL> self . name = name <EOL> self . users = { } <EOL> self . meta = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> } <EOL> def _ebUserCall ( self , err , p ) : <EOL> return failure . Failure ( Exception ( p , err ) ) <EOL> def _cbUserCall ( self , results ) : <EOL> for ( success , result ) in results : <EOL> if not success : <EOL> user , err = result . value <EOL> self . remove ( user , err . getErrorMessage ( ) ) <EOL> def add ( self , user ) : <EOL> assert iwords . IChatClient . providedBy ( user ) , "<STR_LIT>" % ( user , ) <EOL> if user . name not in self . users : <EOL> additions = [ ] <EOL> self . users [ user . name ] = user <EOL> for p in self . users . itervalues ( ) : <EOL> if p is not user : <EOL> d = defer . maybeDeferred ( p . userJoined , self , user ) <EOL> d . addErrback ( self . _ebUserCall , p = p ) <EOL> additions . append ( d ) <EOL> defer . DeferredList ( additions ) . addCallback ( self . _cbUserCall ) <EOL> return defer . succeed ( None ) <EOL> def remove ( self , user , reason = None ) : <EOL> assert reason is None or isinstance ( reason , unicode ) <EOL> try : <EOL> del self . users [ user . name ] <EOL> except KeyError : <EOL> pass <EOL> else : <EOL> removals = [ ] <EOL> for p in self . users . itervalues ( ) : <EOL> if p is not user : <EOL> d = defer . maybeDeferred ( p . userLeft , self , user , reason ) <EOL> d . addErrback ( self . _ebUserCall , p = p ) <EOL> removals . append ( d ) <EOL> defer . DeferredList ( removals ) . addCallback ( self . _cbUserCall ) <EOL> return defer . succeed ( None ) <EOL> def size ( self ) : <EOL> return defer . succeed ( len ( self . users ) ) <EOL> def receive ( self , sender , recipient , message ) : <EOL> assert recipient is self <EOL> receives = [ ] <EOL> for p in self . users . itervalues ( ) : <EOL> if p is not sender : <EOL> d = defer . maybeDeferred ( p . receive , sender , self , message ) <EOL> d . addErrback ( self . _ebUserCall , p = p ) <EOL> receives . append ( d ) <EOL> defer . DeferredList ( receives ) . addCallback ( self . _cbUserCall ) <EOL> return defer . succeed ( None ) <EOL> def setMetadata ( self , meta ) : <EOL> self . meta = meta <EOL> sets = [ ] <EOL> for p in self . users . itervalues ( ) : <EOL> d = defer . maybeDeferred ( p . groupMetaUpdate , self , meta ) <EOL> d . addErrback ( self . _ebUserCall , p = p ) <EOL> sets . append ( d ) <EOL> defer . DeferredList ( sets ) . addCallback ( self . _cbUserCall ) <EOL> return defer . succeed ( None ) <EOL> def iterusers ( self ) : <EOL> return iter ( self . users . values ( ) ) <EOL> class User ( object ) : <EOL> implements ( iwords . IUser ) <EOL> realm = None <EOL> mind = None <EOL> def __init__ ( self , name ) : <EOL> self . name = name <EOL> self . groups = [ ] <EOL> self . lastMessage = time ( ) <EOL> def loggedIn ( self , realm , mind ) : <EOL> self . realm = realm <EOL> self . mind = mind <EOL> self . signOn = time ( ) <EOL> def join ( self , group ) : <EOL> def cbJoin ( result ) : <EOL> self . groups . append ( group ) <EOL> return result <EOL> return group . add ( self . mind ) . addCallback ( cbJoin ) <EOL> def leave ( self , group , reason = None ) : <EOL> def cbLeave ( result ) : <EOL> self . groups . remove ( group ) <EOL> return result <EOL> return group . remove ( self . mind , reason ) . addCallback ( cbLeave ) <EOL> def send ( self , recipient , message ) : <EOL> self . lastMessage = time ( ) <EOL> return recipient . receive ( self . mind , recipient , message ) <EOL> def itergroups ( self ) : <EOL> return iter ( self . groups ) <EOL> def logout ( self ) : <EOL> for g in self . groups [ : ] : <EOL> self . leave ( g ) <EOL> NICKSERV = '<STR_LIT>' <EOL> class IRCUser ( irc . IRC ) : <EOL> """<STR_LIT>""" <EOL> implements ( iwords . IChatClient ) <EOL> groups = None <EOL> logout = None <EOL> avatar = None <EOL> realm = None <EOL> encoding = '<STR_LIT:utf-8>' <EOL> def connectionMade ( self ) : <EOL> self . irc_PRIVMSG = self . irc_NICKSERV_PRIVMSG <EOL> self . realm = self . factory . realm <EOL> self . hostname = self . realm . name <EOL> def connectionLost ( self , reason ) : <EOL> if self . logout is not None : <EOL> self . logout ( ) <EOL> self . avatar = None <EOL> def sendMessage ( self , command , * parameter_list , ** kw ) : <EOL> if '<STR_LIT>' not in kw : <EOL> kw [ '<STR_LIT>' ] = self . hostname <EOL> if '<STR_LIT:to>' not in kw : <EOL> kw [ '<STR_LIT:to>' ] = self . name . encode ( self . encoding ) <EOL> arglist = [ self , command , kw [ '<STR_LIT:to>' ] ] + list ( parameter_list ) <EOL> irc . IRC . sendMessage ( * arglist , ** kw ) <EOL> def userJoined ( self , group , user ) : <EOL> self . join ( <EOL> "<STR_LIT>" % ( user . name , user . name , self . hostname ) , <EOL> '<STR_LIT:#>' + group . name ) <EOL> def userLeft ( self , group , user , reason = None ) : <EOL> assert reason is None or isinstance ( reason , unicode ) <EOL> self . part ( <EOL> "<STR_LIT>" % ( user . name , user . name , self . hostname ) , <EOL> '<STR_LIT:#>' + group . name , <EOL> ( reason or u"<STR_LIT>" ) . encode ( self . encoding , '<STR_LIT:replace>' ) ) <EOL> def receive ( self , sender , recipient , message ) : <EOL> if iwords . IGroup . providedBy ( recipient ) : <EOL> recipientName = '<STR_LIT:#>' + recipient . name <EOL> else : <EOL> recipientName = recipient . name <EOL> text = message . get ( '<STR_LIT:text>' , '<STR_LIT>' ) <EOL> for L in text . splitlines ( ) : <EOL> self . privmsg ( <EOL> '<STR_LIT>' % ( sender . name , sender . name , self . hostname ) , <EOL> recipientName , <EOL> L ) <EOL> def groupMetaUpdate ( self , group , meta ) : <EOL> if '<STR_LIT>' in meta : <EOL> topic = meta [ '<STR_LIT>' ] <EOL> author = meta . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . topic ( <EOL> self . name , <EOL> '<STR_LIT:#>' + group . name , <EOL> topic , <EOL> '<STR_LIT>' % ( author , author , self . hostname ) <EOL> ) <EOL> nickname = None <EOL> password = None <EOL> def irc_PASS ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> self . password = params [ - <NUM_LIT:1> ] <EOL> def irc_NICK ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> nickname = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . privmsg ( <EOL> NICKSERV , <EOL> nickname , <EOL> '<STR_LIT>' ) <EOL> self . transport . loseConnection ( ) <EOL> return <EOL> self . nickname = nickname <EOL> self . name = nickname <EOL> for code , text in self . _motdMessages : <EOL> self . sendMessage ( code , text % self . factory . _serverInfo ) <EOL> if self . password is None : <EOL> self . privmsg ( <EOL> NICKSERV , <EOL> nickname , <EOL> '<STR_LIT>' ) <EOL> else : <EOL> password = self . password <EOL> self . password = None <EOL> self . logInAs ( nickname , password ) <EOL> def irc_USER ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> self . realname = params [ - <NUM_LIT:1> ] <EOL> def irc_NICKSERV_PRIVMSG ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> target = params [ <NUM_LIT:0> ] <EOL> password = params [ - <NUM_LIT:1> ] <EOL> if self . nickname is None : <EOL> self . transport . loseConnection ( ) <EOL> elif target . lower ( ) != "<STR_LIT>" : <EOL> self . privmsg ( <EOL> NICKSERV , <EOL> self . nickname , <EOL> "<STR_LIT>" ) <EOL> else : <EOL> nickname = self . nickname <EOL> self . nickname = None <EOL> self . logInAs ( nickname , password ) <EOL> def logInAs ( self , nickname , password ) : <EOL> d = self . factory . portal . login ( <EOL> credentials . UsernamePassword ( nickname , password ) , <EOL> self , <EOL> iwords . IUser ) <EOL> d . addCallbacks ( self . _cbLogin , self . _ebLogin , errbackArgs = ( nickname , ) ) <EOL> _welcomeMessages = [ <EOL> ( irc . RPL_WELCOME , <EOL> "<STR_LIT>" ) , <EOL> ( irc . RPL_YOURHOST , <EOL> "<STR_LIT>" ) , <EOL> ( irc . RPL_CREATED , <EOL> "<STR_LIT>" ) , <EOL> ( irc . RPL_MYINFO , <EOL> "<STR_LIT>" ) <EOL> ] <EOL> _motdMessages = [ <EOL> ( irc . RPL_MOTDSTART , <EOL> "<STR_LIT>" ) , <EOL> ( irc . RPL_ENDOFMOTD , <EOL> "<STR_LIT>" ) <EOL> ] <EOL> def _cbLogin ( self , ( iface , avatar , logout ) ) : <EOL> assert iface is iwords . IUser , "<STR_LIT>" % ( iface , ) <EOL> del self . irc_PRIVMSG <EOL> self . avatar = avatar <EOL> self . logout = logout <EOL> for code , text in self . _welcomeMessages : <EOL> self . sendMessage ( code , text % self . factory . _serverInfo ) <EOL> def _ebLogin ( self , err , nickname ) : <EOL> if err . check ( ewords . AlreadyLoggedIn ) : <EOL> self . privmsg ( <EOL> NICKSERV , <EOL> nickname , <EOL> "<STR_LIT>" ) <EOL> elif err . check ( ecred . UnauthorizedLogin ) : <EOL> self . privmsg ( <EOL> NICKSERV , <EOL> nickname , <EOL> "<STR_LIT>" ) <EOL> else : <EOL> log . msg ( "<STR_LIT>" ) <EOL> log . err ( err ) <EOL> self . privmsg ( <EOL> NICKSERV , <EOL> nickname , <EOL> "<STR_LIT>" ) <EOL> self . transport . loseConnection ( ) <EOL> def irc_PING ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> if self . realm is not None : <EOL> self . sendMessage ( '<STR_LIT>' , self . hostname ) <EOL> def irc_QUIT ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> self . transport . loseConnection ( ) <EOL> def _channelMode ( self , group , modes = None , * args ) : <EOL> if modes : <EOL> self . sendMessage ( <EOL> irc . ERR_UNKNOWNMODE , <EOL> "<STR_LIT>" ) <EOL> else : <EOL> self . channelMode ( self . name , '<STR_LIT:#>' + group . name , '<STR_LIT:+>' ) <EOL> def _userMode ( self , user , modes = None ) : <EOL> if modes : <EOL> self . sendMessage ( <EOL> irc . ERR_UNKNOWNMODE , <EOL> "<STR_LIT>" ) <EOL> elif user is self . avatar : <EOL> self . sendMessage ( <EOL> irc . RPL_UMODEIS , <EOL> "<STR_LIT:+>" ) <EOL> else : <EOL> self . sendMessage ( <EOL> irc . ERR_USERSDONTMATCH , <EOL> "<STR_LIT>" ) <EOL> def irc_MODE ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> channelOrUser = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHNICK , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> if channelOrUser . startswith ( '<STR_LIT:#>' ) : <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> d = self . realm . lookupGroup ( channelOrUser [ <NUM_LIT:1> : ] ) <EOL> d . addCallbacks ( <EOL> self . _channelMode , <EOL> ebGroup , <EOL> callbackArgs = tuple ( params [ <NUM_LIT:1> : ] ) ) <EOL> else : <EOL> def ebUser ( err ) : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHNICK , <EOL> "<STR_LIT>" ) <EOL> d = self . realm . lookupUser ( channelOrUser ) <EOL> d . addCallbacks ( <EOL> self . _userMode , <EOL> ebUser , <EOL> callbackArgs = tuple ( params [ <NUM_LIT:1> : ] ) ) <EOL> def irc_USERHOST ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def irc_PRIVMSG ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> targetName = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHNICK , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> messageText = params [ - <NUM_LIT:1> ] <EOL> if targetName . startswith ( '<STR_LIT:#>' ) : <EOL> target = self . realm . lookupGroup ( targetName [ <NUM_LIT:1> : ] ) <EOL> else : <EOL> target = self . realm . lookupUser ( targetName ) . addCallback ( lambda user : user . mind ) <EOL> def cbTarget ( targ ) : <EOL> if targ is not None : <EOL> return self . avatar . send ( targ , { "<STR_LIT:text>" : messageText } ) <EOL> def ebTarget ( err ) : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHNICK , targetName , <EOL> "<STR_LIT>" ) <EOL> target . addCallbacks ( cbTarget , ebTarget ) <EOL> def irc_JOIN ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> groupName = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> if groupName . startswith ( '<STR_LIT:#>' ) : <EOL> groupName = groupName [ <NUM_LIT:1> : ] <EOL> def cbGroup ( group ) : <EOL> def cbJoin ( ign ) : <EOL> self . userJoined ( group , self ) <EOL> self . names ( <EOL> self . name , <EOL> '<STR_LIT:#>' + group . name , <EOL> [ user . name for user in group . iterusers ( ) ] ) <EOL> self . _sendTopic ( group ) <EOL> return self . avatar . join ( group ) . addCallback ( cbJoin ) <EOL> def ebGroup ( err ) : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , '<STR_LIT:#>' + groupName , <EOL> "<STR_LIT>" ) <EOL> self . realm . getGroup ( groupName ) . addCallbacks ( cbGroup , ebGroup ) <EOL> def irc_PART ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> groupName = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOTONCHANNEL , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> if groupName . startswith ( '<STR_LIT:#>' ) : <EOL> groupName = groupName [ <NUM_LIT:1> : ] <EOL> if len ( params ) > <NUM_LIT:1> : <EOL> reason = params [ <NUM_LIT:1> ] . decode ( '<STR_LIT:utf-8>' ) <EOL> else : <EOL> reason = None <EOL> def cbGroup ( group ) : <EOL> def cbLeave ( result ) : <EOL> self . userLeft ( group , self , reason ) <EOL> return self . avatar . leave ( group , reason ) . addCallback ( cbLeave ) <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> self . sendMessage ( <EOL> irc . ERR_NOTONCHANNEL , <EOL> '<STR_LIT:#>' + groupName , <EOL> "<STR_LIT::>" + err . getErrorMessage ( ) ) <EOL> self . realm . lookupGroup ( groupName ) . addCallbacks ( cbGroup , ebGroup ) <EOL> def irc_NAMES ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> channel = params [ - <NUM_LIT:1> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , params [ - <NUM_LIT:1> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> if channel . startswith ( '<STR_LIT:#>' ) : <EOL> channel = channel [ <NUM_LIT:1> : ] <EOL> def cbGroup ( group ) : <EOL> self . names ( <EOL> self . name , <EOL> '<STR_LIT:#>' + group . name , <EOL> [ user . name for user in group . iterusers ( ) ] ) <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> self . names ( <EOL> self . name , <EOL> '<STR_LIT:#>' + channel , <EOL> [ ] ) <EOL> self . realm . lookupGroup ( channel ) . addCallbacks ( cbGroup , ebGroup ) <EOL> def irc_TOPIC ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> channel = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , <EOL> "<STR_LIT>" ) <EOL> return <EOL> if channel . startswith ( '<STR_LIT:#>' ) : <EOL> channel = channel [ <NUM_LIT:1> : ] <EOL> if len ( params ) > <NUM_LIT:1> : <EOL> self . _setTopic ( channel , params [ <NUM_LIT:1> ] ) <EOL> else : <EOL> self . _getTopic ( channel ) <EOL> def _sendTopic ( self , group ) : <EOL> """<STR_LIT>""" <EOL> topic = group . meta . get ( "<STR_LIT>" ) <EOL> if topic : <EOL> author = group . meta . get ( "<STR_LIT>" ) or "<STR_LIT>" <EOL> date = group . meta . get ( "<STR_LIT>" , <NUM_LIT:0> ) <EOL> self . topic ( self . name , '<STR_LIT:#>' + group . name , topic ) <EOL> self . topicAuthor ( self . name , '<STR_LIT:#>' + group . name , author , date ) <EOL> def _getTopic ( self , channel ) : <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , '<STR_LIT:=>' , channel , <EOL> "<STR_LIT>" ) <EOL> self . realm . lookupGroup ( channel ) . addCallbacks ( self . _sendTopic , ebGroup ) <EOL> def _setTopic ( self , channel , topic ) : <EOL> def cbGroup ( group ) : <EOL> newMeta = group . meta . copy ( ) <EOL> newMeta [ '<STR_LIT>' ] = topic <EOL> newMeta [ '<STR_LIT>' ] = self . name <EOL> newMeta [ '<STR_LIT>' ] = int ( time ( ) ) <EOL> def ebSet ( err ) : <EOL> self . sendMessage ( <EOL> irc . ERR_CHANOPRIVSNEEDED , <EOL> "<STR_LIT:#>" + group . name , <EOL> "<STR_LIT>" ) <EOL> return group . setMetadata ( newMeta ) . addErrback ( ebSet ) <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , '<STR_LIT:=>' , channel , <EOL> "<STR_LIT>" ) <EOL> self . realm . lookupGroup ( channel ) . addCallbacks ( cbGroup , ebGroup ) <EOL> def list ( self , channels ) : <EOL> """<STR_LIT>""" <EOL> for ( name , size , topic ) in channels : <EOL> self . sendMessage ( irc . RPL_LIST , name , str ( size ) , "<STR_LIT::>" + topic ) <EOL> self . sendMessage ( irc . RPL_LISTEND , "<STR_LIT>" ) <EOL> def irc_LIST ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> if params : <EOL> try : <EOL> channels = params [ <NUM_LIT:0> ] . decode ( self . encoding ) . split ( '<STR_LIT:U+002C>' ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHCHANNEL , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> groups = [ ] <EOL> for ch in channels : <EOL> if ch . startswith ( '<STR_LIT:#>' ) : <EOL> ch = ch [ <NUM_LIT:1> : ] <EOL> groups . append ( self . realm . lookupGroup ( ch ) ) <EOL> groups = defer . DeferredList ( groups , consumeErrors = True ) <EOL> groups . addCallback ( lambda gs : [ r for ( s , r ) in gs if s ] ) <EOL> else : <EOL> groups = self . realm . itergroups ( ) <EOL> def cbGroups ( groups ) : <EOL> def gotSize ( size , group ) : <EOL> return group . name , size , group . meta . get ( '<STR_LIT>' ) <EOL> d = defer . DeferredList ( [ <EOL> group . size ( ) . addCallback ( gotSize , group ) for group in groups ] ) <EOL> d . addCallback ( lambda results : self . list ( [ r for ( s , r ) in results if s ] ) ) <EOL> return d <EOL> groups . addCallback ( cbGroups ) <EOL> def _channelWho ( self , group ) : <EOL> self . who ( self . name , '<STR_LIT:#>' + group . name , <EOL> [ ( m . name , self . hostname , self . realm . name , m . name , "<STR_LIT:H>" , <NUM_LIT:0> , m . name ) for m in group . iterusers ( ) ] ) <EOL> def _userWho ( self , user ) : <EOL> self . sendMessage ( irc . RPL_ENDOFWHO , <EOL> "<STR_LIT>" ) <EOL> def irc_WHO ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> if not params : <EOL> self . sendMessage ( irc . RPL_ENDOFWHO , "<STR_LIT>" ) <EOL> return <EOL> try : <EOL> channelOrUser = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . RPL_ENDOFWHO , params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> if channelOrUser . startswith ( '<STR_LIT:#>' ) : <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> self . sendMessage ( <EOL> irc . RPL_ENDOFWHO , channelOrUser , <EOL> "<STR_LIT>" ) <EOL> d = self . realm . lookupGroup ( channelOrUser [ <NUM_LIT:1> : ] ) <EOL> d . addCallbacks ( self . _channelWho , ebGroup ) <EOL> else : <EOL> def ebUser ( err ) : <EOL> err . trap ( ewords . NoSuchUser ) <EOL> self . sendMessage ( <EOL> irc . RPL_ENDOFWHO , channelOrUser , <EOL> "<STR_LIT>" ) <EOL> d = self . realm . lookupUser ( channelOrUser ) <EOL> d . addCallbacks ( self . _userWho , ebUser ) <EOL> def irc_WHOIS ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> def cbUser ( user ) : <EOL> self . whois ( <EOL> self . name , <EOL> user . name , user . name , self . realm . name , <EOL> user . name , self . realm . name , '<STR_LIT>' , False , <EOL> int ( time ( ) - user . lastMessage ) , user . signOn , <EOL> [ '<STR_LIT:#>' + group . name for group in user . itergroups ( ) ] ) <EOL> def ebUser ( err ) : <EOL> err . trap ( ewords . NoSuchUser ) <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHNICK , <EOL> params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> try : <EOL> user = params [ <NUM_LIT:0> ] . decode ( self . encoding ) <EOL> except UnicodeDecodeError : <EOL> self . sendMessage ( <EOL> irc . ERR_NOSUCHNICK , <EOL> params [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" ) <EOL> return <EOL> self . realm . lookupUser ( user ) . addCallbacks ( cbUser , ebUser ) <EOL> def irc_OPER ( self , prefix , params ) : <EOL> """<STR_LIT>""" <EOL> self . sendMessage ( irc . ERR_NOOPERHOST , "<STR_LIT>" ) <EOL> class IRCFactory ( protocol . ServerFactory ) : <EOL> """<STR_LIT>""" <EOL> protocol = IRCUser <EOL> def __init__ ( self , realm , portal ) : <EOL> self . realm = realm <EOL> self . portal = portal <EOL> self . _serverInfo = { <EOL> "<STR_LIT>" : self . realm . name , <EOL> "<STR_LIT>" : copyright . version , <EOL> "<STR_LIT>" : ctime ( ) <EOL> } <EOL> class PBMind ( pb . Referenceable ) : <EOL> def __init__ ( self ) : <EOL> pass <EOL> def jellyFor ( self , jellier ) : <EOL> return reflect . qual ( PBMind ) , jellier . invoker . registerReference ( self ) <EOL> def remote_userJoined ( self , user , group ) : <EOL> pass <EOL> def remote_userLeft ( self , user , group , reason ) : <EOL> pass <EOL> def remote_receive ( self , sender , recipient , message ) : <EOL> pass <EOL> def remote_groupMetaUpdate ( self , group , meta ) : <EOL> pass <EOL> class PBMindReference ( pb . RemoteReference ) : <EOL> implements ( iwords . IChatClient ) <EOL> def receive ( self , sender , recipient , message ) : <EOL> if iwords . IGroup . providedBy ( recipient ) : <EOL> rec = PBGroup ( self . realm , self . avatar , recipient ) <EOL> else : <EOL> rec = PBUser ( self . realm , self . avatar , recipient ) <EOL> return self . callRemote ( <EOL> '<STR_LIT>' , <EOL> PBUser ( self . realm , self . avatar , sender ) , <EOL> rec , <EOL> message ) <EOL> def groupMetaUpdate ( self , group , meta ) : <EOL> return self . callRemote ( <EOL> '<STR_LIT>' , <EOL> PBGroup ( self . realm , self . avatar , group ) , <EOL> meta ) <EOL> def userJoined ( self , group , user ) : <EOL> return self . callRemote ( <EOL> '<STR_LIT>' , <EOL> PBGroup ( self . realm , self . avatar , group ) , <EOL> PBUser ( self . realm , self . avatar , user ) ) <EOL> def userLeft ( self , group , user , reason = None ) : <EOL> assert reason is None or isinstance ( reason , unicode ) <EOL> return self . callRemote ( <EOL> '<STR_LIT>' , <EOL> PBGroup ( self . realm , self . avatar , group ) , <EOL> PBUser ( self . realm , self . avatar , user ) , <EOL> reason ) <EOL> pb . setUnjellyableForClass ( PBMind , PBMindReference ) <EOL> class PBGroup ( pb . Referenceable ) : <EOL> def __init__ ( self , realm , avatar , group ) : <EOL> self . realm = realm <EOL> self . avatar = avatar <EOL> self . group = group <EOL> def processUniqueID ( self ) : <EOL> return hash ( ( self . realm . name , self . avatar . name , self . group . name ) ) <EOL> def jellyFor ( self , jellier ) : <EOL> return reflect . qual ( self . __class__ ) , self . group . name . encode ( '<STR_LIT:utf-8>' ) , jellier . invoker . registerReference ( self ) <EOL> def remote_leave ( self , reason = None ) : <EOL> return self . avatar . leave ( self . group , reason ) <EOL> def remote_send ( self , message ) : <EOL> return self . avatar . send ( self . group , message ) <EOL> class PBGroupReference ( pb . RemoteReference ) : <EOL> implements ( iwords . IGroup ) <EOL> def unjellyFor ( self , unjellier , unjellyList ) : <EOL> clsName , name , ref = unjellyList <EOL> self . name = name . decode ( '<STR_LIT:utf-8>' ) <EOL> return pb . RemoteReference . unjellyFor ( self , unjellier , [ clsName , ref ] ) <EOL> def leave ( self , reason = None ) : <EOL> return self . callRemote ( "<STR_LIT>" , reason ) <EOL> def send ( self , message ) : <EOL> return self . callRemote ( "<STR_LIT>" , message ) <EOL> pb . setUnjellyableForClass ( PBGroup , PBGroupReference ) <EOL> class PBUser ( pb . Referenceable ) : <EOL> def __init__ ( self , realm , avatar , user ) : <EOL> self . realm = realm <EOL> self . avatar = avatar <EOL> self . user = user <EOL> def processUniqueID ( self ) : <EOL> return hash ( ( self . realm . name , self . avatar . name , self . user . name ) ) <EOL> class ChatAvatar ( pb . Referenceable ) : <EOL> implements ( iwords . IChatClient ) <EOL> def __init__ ( self , avatar ) : <EOL> self . avatar = avatar <EOL> def jellyFor ( self , jellier ) : <EOL> return reflect . qual ( self . __class__ ) , jellier . invoker . registerReference ( self ) <EOL> def remote_join ( self , groupName ) : <EOL> assert isinstance ( groupName , unicode ) <EOL> def cbGroup ( group ) : <EOL> def cbJoin ( ignored ) : <EOL> return PBGroup ( self . avatar . realm , self . avatar , group ) <EOL> d = self . avatar . join ( group ) <EOL> d . addCallback ( cbJoin ) <EOL> return d <EOL> d = self . avatar . realm . getGroup ( groupName ) <EOL> d . addCallback ( cbGroup ) <EOL> return d <EOL> registerAdapter ( ChatAvatar , iwords . IUser , pb . IPerspective ) <EOL> class AvatarReference ( pb . RemoteReference ) : <EOL> def join ( self , groupName ) : <EOL> return self . callRemote ( '<STR_LIT>' , groupName ) <EOL> def quit ( self ) : <EOL> d = defer . Deferred ( ) <EOL> self . broker . notifyOnDisconnect ( lambda : d . callback ( None ) ) <EOL> self . broker . transport . loseConnection ( ) <EOL> return d <EOL> pb . setUnjellyableForClass ( ChatAvatar , AvatarReference ) <EOL> class WordsRealm ( object ) : <EOL> implements ( portal . IRealm , iwords . IChatService ) <EOL> _encoding = '<STR_LIT:utf-8>' <EOL> def __init__ ( self , name ) : <EOL> self . name = name <EOL> def userFactory ( self , name ) : <EOL> return User ( name ) <EOL> def groupFactory ( self , name ) : <EOL> return Group ( name ) <EOL> def logoutFactory ( self , avatar , facet ) : <EOL> def logout ( ) : <EOL> getattr ( facet , '<STR_LIT>' , lambda : None ) ( ) <EOL> avatar . realm = avatar . mind = None <EOL> return logout <EOL> def requestAvatar ( self , avatarId , mind , * interfaces ) : <EOL> if isinstance ( avatarId , str ) : <EOL> avatarId = avatarId . decode ( self . _encoding ) <EOL> def gotAvatar ( avatar ) : <EOL> if avatar . realm is not None : <EOL> raise ewords . AlreadyLoggedIn ( ) <EOL> for iface in interfaces : <EOL> facet = iface ( avatar , None ) <EOL> if facet is not None : <EOL> avatar . loggedIn ( self , mind ) <EOL> mind . name = avatarId <EOL> mind . realm = self <EOL> mind . avatar = avatar <EOL> return iface , facet , self . logoutFactory ( avatar , facet ) <EOL> raise NotImplementedError ( self , interfaces ) <EOL> return self . getUser ( avatarId ) . addCallback ( gotAvatar ) <EOL> createGroupOnRequest = False <EOL> createUserOnRequest = True <EOL> def lookupUser ( self , name ) : <EOL> raise NotImplementedError <EOL> def lookupGroup ( self , group ) : <EOL> raise NotImplementedError <EOL> def addUser ( self , user ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> def addGroup ( self , group ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> def getGroup ( self , name ) : <EOL> assert isinstance ( name , unicode ) <EOL> if self . createGroupOnRequest : <EOL> def ebGroup ( err ) : <EOL> err . trap ( ewords . DuplicateGroup ) <EOL> return self . lookupGroup ( name ) <EOL> return self . createGroup ( name ) . addErrback ( ebGroup ) <EOL> return self . lookupGroup ( name ) <EOL> def getUser ( self , name ) : <EOL> assert isinstance ( name , unicode ) <EOL> if self . createUserOnRequest : <EOL> def ebUser ( err ) : <EOL> err . trap ( ewords . DuplicateUser ) <EOL> return self . lookupUser ( name ) <EOL> return self . createUser ( name ) . addErrback ( ebUser ) <EOL> return self . lookupUser ( name ) <EOL> def createUser ( self , name ) : <EOL> assert isinstance ( name , unicode ) <EOL> def cbLookup ( user ) : <EOL> return failure . Failure ( ewords . DuplicateUser ( name ) ) <EOL> def ebLookup ( err ) : <EOL> err . trap ( ewords . NoSuchUser ) <EOL> return self . userFactory ( name ) <EOL> name = name . lower ( ) <EOL> d = self . lookupUser ( name ) <EOL> d . addCallbacks ( cbLookup , ebLookup ) <EOL> d . addCallback ( self . addUser ) <EOL> return d <EOL> def createGroup ( self , name ) : <EOL> assert isinstance ( name , unicode ) <EOL> def cbLookup ( group ) : <EOL> return failure . Failure ( ewords . DuplicateGroup ( name ) ) <EOL> def ebLookup ( err ) : <EOL> err . trap ( ewords . NoSuchGroup ) <EOL> return self . groupFactory ( name ) <EOL> name = name . lower ( ) <EOL> d = self . lookupGroup ( name ) <EOL> d . addCallbacks ( cbLookup , ebLookup ) <EOL> d . addCallback ( self . addGroup ) <EOL> return d <EOL> class InMemoryWordsRealm ( WordsRealm ) : <EOL> def __init__ ( self , * a , ** kw ) : <EOL> super ( InMemoryWordsRealm , self ) . __init__ ( * a , ** kw ) <EOL> self . users = { } <EOL> self . groups = { } <EOL> def itergroups ( self ) : <EOL> return defer . succeed ( self . groups . itervalues ( ) ) <EOL> def addUser ( self , user ) : <EOL> if user . name in self . users : <EOL> return defer . fail ( failure . Failure ( ewords . DuplicateUser ( ) ) ) <EOL> self . users [ user . name ] = user <EOL> return defer . succeed ( user ) <EOL> def addGroup ( self , group ) : <EOL> if group . name in self . groups : <EOL> return defer . fail ( failure . Failure ( ewords . DuplicateGroup ( ) ) ) <EOL> self . groups [ group . name ] = group <EOL> return defer . succeed ( group ) <EOL> def lookupUser ( self , name ) : <EOL> assert isinstance ( name , unicode ) <EOL> name = name . lower ( ) <EOL> try : <EOL> user = self . users [ name ] <EOL> except KeyError : <EOL> return defer . fail ( failure . Failure ( ewords . NoSuchUser ( name ) ) ) <EOL> else : <EOL> return defer . succeed ( user ) <EOL> def lookupGroup ( self , name ) : <EOL> assert isinstance ( name , unicode ) <EOL> name = name . lower ( ) <EOL> try : <EOL> group = self . groups [ name ] <EOL> except KeyError : <EOL> return defer . fail ( failure . Failure ( ewords . NoSuchGroup ( name ) ) ) <EOL> else : <EOL> return defer . succeed ( group ) <EOL> __all__ = [ <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> ] </s>
