<s> import re <EOL> import copy <EOL> import time <EOL> import random <EOL> import base64 <EOL> import collections <EOL> try : <EOL> from ecdsa import SigningKey , BadDigestError <EOL> ecdsa = True <EOL> except ImportError : <EOL> ecdsa = False <EOL> from . import conf , ircdb , ircmsgs , ircutils , log , utils , world <EOL> from . utils . str import rsplit <EOL> from . utils . iter import chain <EOL> from . utils . structures import smallqueue , RingBuffer <EOL> class IrcCommandDispatcher ( object ) : <EOL> """<STR_LIT>""" <EOL> def dispatchCommand ( self , command ) : <EOL> """<STR_LIT>""" <EOL> return getattr ( self , '<STR_LIT>' + command . capitalize ( ) , None ) <EOL> class IrcCallback ( IrcCommandDispatcher , log . Firewalled ) : <EOL> """<STR_LIT>""" <EOL> callAfter = ( ) <EOL> callBefore = ( ) <EOL> __firewalled__ = { '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : lambda self , irc , msg : msg , <EOL> '<STR_LIT>' : lambda self , irc , msg : msg , <EOL> '<STR_LIT:name>' : lambda self : self . __class__ . __name__ , <EOL> '<STR_LIT>' : lambda self , irc : ( [ ] , [ ] ) , <EOL> } <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> pass <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , self . name ( ) , object . __repr__ ( self ) ) <EOL> def name ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . __class__ . __name__ <EOL> def callPrecedence ( self , irc ) : <EOL> """<STR_LIT>""" <EOL> after = [ ] <EOL> before = [ ] <EOL> for name in self . callBefore : <EOL> cb = irc . getCallback ( name ) <EOL> if cb is not None : <EOL> after . append ( cb ) <EOL> for name in self . callAfter : <EOL> cb = irc . getCallback ( name ) <EOL> if cb is not None : <EOL> before . append ( cb ) <EOL> assert self not in after , '<STR_LIT>' % self . name ( ) <EOL> assert self not in before , '<STR_LIT>' % self . name ( ) <EOL> return ( before , after ) <EOL> def inFilter ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> return msg <EOL> def outFilter ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> return msg <EOL> def __call__ ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> method = self . dispatchCommand ( msg . command ) <EOL> if method is not None : <EOL> method ( irc , msg ) <EOL> def reset ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def die ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> _high = frozenset ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> _low = frozenset ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> class IrcMsgQueue ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def __init__ ( self , iterable = ( ) ) : <EOL> self . reset ( ) <EOL> for msg in iterable : <EOL> self . enqueue ( msg ) <EOL> def reset ( self ) : <EOL> """<STR_LIT>""" <EOL> self . lastJoin = <NUM_LIT:0> <EOL> self . highpriority = smallqueue ( ) <EOL> self . normal = smallqueue ( ) <EOL> self . lowpriority = smallqueue ( ) <EOL> def enqueue ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> if msg in self and conf . supybot . protocols . irc . queuing . duplicates ( ) : <EOL> s = str ( msg ) . strip ( ) <EOL> log . info ( '<STR_LIT>' , s ) <EOL> return False <EOL> else : <EOL> if msg . command in _high : <EOL> self . highpriority . enqueue ( msg ) <EOL> elif msg . command in _low : <EOL> self . lowpriority . enqueue ( msg ) <EOL> else : <EOL> self . normal . enqueue ( msg ) <EOL> return True <EOL> def dequeue ( self ) : <EOL> """<STR_LIT>""" <EOL> msg = None <EOL> if self . highpriority : <EOL> msg = self . highpriority . dequeue ( ) <EOL> elif self . normal : <EOL> msg = self . normal . dequeue ( ) <EOL> elif self . lowpriority : <EOL> msg = self . lowpriority . dequeue ( ) <EOL> if msg . command == '<STR_LIT>' : <EOL> limit = conf . supybot . protocols . irc . queuing . rateLimit . join ( ) <EOL> now = time . time ( ) <EOL> if self . lastJoin + limit <= now : <EOL> self . lastJoin = now <EOL> else : <EOL> self . lowpriority . enqueue ( msg ) <EOL> msg = None <EOL> return msg <EOL> def __contains__ ( self , msg ) : <EOL> return msg in self . normal or msg in self . lowpriority or msg in self . highpriority <EOL> def __bool__ ( self ) : <EOL> return bool ( self . highpriority or self . normal or self . lowpriority ) <EOL> __nonzero__ = __bool__ <EOL> def __len__ ( self ) : <EOL> return len ( self . highpriority ) + len ( self . lowpriority ) + len ( self . normal ) <EOL> def __repr__ ( self ) : <EOL> name = self . __class__ . __name__ <EOL> return '<STR_LIT>' % ( name , list ( chain ( self . highpriority , <EOL> self . normal , <EOL> self . lowpriority ) ) ) <EOL> __str__ = __repr__ <EOL> class ChannelState ( utils . python . Object ) : <EOL> __slots__ = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def __init__ ( self ) : <EOL> self . topic = '<STR_LIT>' <EOL> self . created = <NUM_LIT:0> <EOL> self . ops = ircutils . IrcSet ( ) <EOL> self . bans = ircutils . IrcSet ( ) <EOL> self . users = ircutils . IrcSet ( ) <EOL> self . voices = ircutils . IrcSet ( ) <EOL> self . halfops = ircutils . IrcSet ( ) <EOL> self . modes = { } <EOL> def isOp ( self , nick ) : <EOL> return nick in self . ops <EOL> def isOpPlus ( self , nick ) : <EOL> return nick in self . ops <EOL> def isVoice ( self , nick ) : <EOL> return nick in self . voices <EOL> def isVoicePlus ( self , nick ) : <EOL> return nick in self . voices or nick in self . halfops or nick in self . ops <EOL> def isHalfop ( self , nick ) : <EOL> return nick in self . halfops <EOL> def isHalfopPlus ( self , nick ) : <EOL> return nick in self . halfops or nick in self . ops <EOL> def addUser ( self , user ) : <EOL> "<STR_LIT>" <EOL> nick = user . lstrip ( '<STR_LIT>' ) <EOL> if not nick : <EOL> return <EOL> while user and user [ <NUM_LIT:0> ] in '<STR_LIT>' : <EOL> ( marker , user ) = ( user [ <NUM_LIT:0> ] , user [ <NUM_LIT:1> : ] ) <EOL> assert user , '<STR_LIT>' <EOL> if marker in '<STR_LIT>' : <EOL> self . ops . add ( nick ) <EOL> elif marker == '<STR_LIT:%>' : <EOL> self . halfops . add ( nick ) <EOL> elif marker == '<STR_LIT:+>' : <EOL> self . voices . add ( nick ) <EOL> self . users . add ( nick ) <EOL> def replaceUser ( self , oldNick , newNick ) : <EOL> """<STR_LIT>""" <EOL> for s in ( self . users , self . ops , self . halfops , self . voices ) : <EOL> if oldNick in s : <EOL> s . remove ( oldNick ) <EOL> s . add ( newNick ) <EOL> def removeUser ( self , user ) : <EOL> """<STR_LIT>""" <EOL> self . users . discard ( user ) <EOL> self . ops . discard ( user ) <EOL> self . halfops . discard ( user ) <EOL> self . voices . discard ( user ) <EOL> def setMode ( self , mode , value = None ) : <EOL> assert mode not in '<STR_LIT>' <EOL> self . modes [ mode ] = value <EOL> def unsetMode ( self , mode ) : <EOL> assert mode not in '<STR_LIT>' <EOL> if mode in self . modes : <EOL> del self . modes [ mode ] <EOL> def doMode ( self , msg ) : <EOL> def getSet ( c ) : <EOL> if c == '<STR_LIT:o>' : <EOL> Set = self . ops <EOL> elif c == '<STR_LIT:v>' : <EOL> Set = self . voices <EOL> elif c == '<STR_LIT:h>' : <EOL> Set = self . halfops <EOL> elif c == '<STR_LIT:b>' : <EOL> Set = self . bans <EOL> else : <EOL> Set = set ( ) <EOL> return Set <EOL> for ( mode , value ) in ircutils . separateModes ( msg . args [ <NUM_LIT:1> : ] ) : <EOL> ( action , modeChar ) = mode <EOL> if modeChar in '<STR_LIT>' : <EOL> Set = getSet ( modeChar ) <EOL> if action == '<STR_LIT:->' : <EOL> Set . discard ( value ) <EOL> elif action == '<STR_LIT:+>' : <EOL> Set . add ( value ) <EOL> else : <EOL> if action == '<STR_LIT:+>' : <EOL> self . setMode ( modeChar , value ) <EOL> else : <EOL> assert action == '<STR_LIT:->' <EOL> self . unsetMode ( modeChar ) <EOL> def __getstate__ ( self ) : <EOL> return [ getattr ( self , name ) for name in self . __slots__ ] <EOL> def __setstate__ ( self , t ) : <EOL> for ( name , value ) in zip ( self . __slots__ , t ) : <EOL> setattr ( self , name , value ) <EOL> def __eq__ ( self , other ) : <EOL> ret = True <EOL> for name in self . __slots__ : <EOL> ret = ret and getattr ( self , name ) == getattr ( other , name ) <EOL> return ret <EOL> Batch = collections . namedtuple ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> class IrcState ( IrcCommandDispatcher , log . Firewalled ) : <EOL> """<STR_LIT>""" <EOL> __firewalled__ = { '<STR_LIT>' : None } <EOL> def __init__ ( self , history = None , supported = None , <EOL> nicksToHostmasks = None , channels = None , <EOL> capabilities_ack = None , capabilities_nak = None , <EOL> capabilities_ls = None ) : <EOL> if history is None : <EOL> history = RingBuffer ( conf . supybot . protocols . irc . maxHistoryLength ( ) ) <EOL> if supported is None : <EOL> supported = utils . InsensitivePreservingDict ( ) <EOL> if nicksToHostmasks is None : <EOL> nicksToHostmasks = ircutils . IrcDict ( ) <EOL> if channels is None : <EOL> channels = ircutils . IrcDict ( ) <EOL> self . capabilities_ack = capabilities_ack or set ( ) <EOL> self . capabilities_nak = capabilities_nak or set ( ) <EOL> self . capabilities_ls = capabilities_ls or { } <EOL> self . ircd = None <EOL> self . supported = supported <EOL> self . history = history <EOL> self . channels = channels <EOL> self . nicksToHostmasks = nicksToHostmasks <EOL> self . batches = { } <EOL> def reset ( self ) : <EOL> """<STR_LIT>""" <EOL> self . history . reset ( ) <EOL> self . channels . clear ( ) <EOL> self . supported . clear ( ) <EOL> self . nicksToHostmasks . clear ( ) <EOL> self . history . resize ( conf . supybot . protocols . irc . maxHistoryLength ( ) ) <EOL> self . batches = { } <EOL> def __reduce__ ( self ) : <EOL> return ( self . __class__ , ( self . history , self . supported , <EOL> self . nicksToHostmasks , self . channels ) ) <EOL> def __eq__ ( self , other ) : <EOL> return self . history == other . history and self . channels == other . channels and self . supported == other . supported and self . nicksToHostmasks == other . nicksToHostmasks and self . batches == other . batches <EOL> def __ne__ ( self , other ) : <EOL> return not self == other <EOL> def copy ( self ) : <EOL> ret = self . __class__ ( ) <EOL> ret . history = copy . deepcopy ( self . history ) <EOL> ret . nicksToHostmasks = copy . deepcopy ( self . nicksToHostmasks ) <EOL> ret . channels = copy . deepcopy ( self . channels ) <EOL> ret . batches = copy . deepcopy ( self . batches ) <EOL> return ret <EOL> def addMsg ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> self . history . append ( msg ) <EOL> if ircutils . isUserHostmask ( msg . prefix ) and not msg . command == '<STR_LIT>' : <EOL> self . nicksToHostmasks [ msg . nick ] = msg . prefix <EOL> if '<STR_LIT>' in msg . server_tags : <EOL> batch = msg . server_tags [ '<STR_LIT>' ] <EOL> assert batch in self . batches , '<STR_LIT>' % batch <EOL> self . batches [ batch ] . messages . append ( msg ) <EOL> method = self . dispatchCommand ( msg . command ) <EOL> if method is not None : <EOL> method ( irc , msg ) <EOL> def getTopic ( self , channel ) : <EOL> """<STR_LIT>""" <EOL> return self . channels [ channel ] . topic <EOL> def nickToHostmask ( self , nick ) : <EOL> """<STR_LIT>""" <EOL> return self . nicksToHostmasks [ nick ] <EOL> def do004 ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> self . ircd = msg . args [ <NUM_LIT:2> ] <EOL> self . supported [ '<STR_LIT>' ] = frozenset ( msg . args [ <NUM_LIT:3> ] ) <EOL> self . supported [ '<STR_LIT>' ] = frozenset ( msg . args [ <NUM_LIT:4> ] ) <EOL> _005converters = utils . InsensitivePreservingDict ( { <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> '<STR_LIT>' : int , <EOL> } ) <EOL> def _prefixParser ( s ) : <EOL> if '<STR_LIT:)>' in s : <EOL> ( left , right ) = s . split ( '<STR_LIT:)>' ) <EOL> assert left [ <NUM_LIT:0> ] == '<STR_LIT:(>' , '<STR_LIT>' % s <EOL> left = left [ <NUM_LIT:1> : ] <EOL> assert len ( left ) == len ( right ) , '<STR_LIT>' % s <EOL> return dict ( list ( zip ( left , right ) ) ) <EOL> else : <EOL> return dict ( list ( zip ( '<STR_LIT>' , s ) ) ) <EOL> _005converters [ '<STR_LIT>' ] = _prefixParser <EOL> del _prefixParser <EOL> def _maxlistParser ( s ) : <EOL> modes = '<STR_LIT>' <EOL> limits = [ ] <EOL> pairs = s . split ( '<STR_LIT:U+002C>' ) <EOL> for pair in pairs : <EOL> ( mode , limit ) = pair . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> modes += mode <EOL> limits += ( int ( limit ) , ) * len ( mode ) <EOL> return dict ( list ( zip ( modes , limits ) ) ) <EOL> _005converters [ '<STR_LIT>' ] = _maxlistParser <EOL> del _maxlistParser <EOL> def _maxbansParser ( s ) : <EOL> if '<STR_LIT::>' in s : <EOL> modes = '<STR_LIT>' <EOL> limits = [ ] <EOL> pairs = s . split ( '<STR_LIT:U+002C>' ) <EOL> for pair in pairs : <EOL> ( mode , limit ) = pair . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> modes += mode <EOL> limits += ( int ( limit ) , ) * len ( mode ) <EOL> d = dict ( list ( zip ( modes , limits ) ) ) <EOL> assert '<STR_LIT:b>' in d <EOL> return d [ '<STR_LIT:b>' ] <EOL> else : <EOL> return int ( s ) <EOL> _005converters [ '<STR_LIT>' ] = _maxbansParser <EOL> del _maxbansParser <EOL> def do005 ( self , irc , msg ) : <EOL> for arg in msg . args [ <NUM_LIT:1> : - <NUM_LIT:1> ] : <EOL> if '<STR_LIT:=>' in arg : <EOL> ( name , value ) = arg . split ( '<STR_LIT:=>' , <NUM_LIT:1> ) <EOL> converter = self . _005converters . get ( name , lambda x : x ) <EOL> try : <EOL> self . supported [ name ] = converter ( value ) <EOL> except Exception : <EOL> log . exception ( '<STR_LIT>' ) <EOL> log . error ( '<STR_LIT>' , name , converter ) <EOL> else : <EOL> self . supported [ arg ] = None <EOL> def do352 ( self , irc , msg ) : <EOL> ( nick , user , host ) = ( msg . args [ <NUM_LIT:5> ] , msg . args [ <NUM_LIT:2> ] , msg . args [ <NUM_LIT:3> ] ) <EOL> hostmask = '<STR_LIT>' % ( nick , user , host ) <EOL> self . nicksToHostmasks [ nick ] = hostmask <EOL> def do354 ( self , irc , msg ) : <EOL> if len ( msg . args ) != <NUM_LIT:6> or msg . args [ <NUM_LIT:1> ] != '<STR_LIT:1>' : <EOL> return <EOL> ( __ , ___ , user , host , nick , ___ ) = msg . args <EOL> hostmask = '<STR_LIT>' % ( nick , user , host ) <EOL> self . nicksToHostmasks [ nick ] = hostmask <EOL> def do353 ( self , irc , msg ) : <EOL> ( __ , type , channel , items ) = msg . args <EOL> if channel not in self . channels : <EOL> self . channels [ channel ] = ChannelState ( ) <EOL> c = self . channels [ channel ] <EOL> for item in items . split ( ) : <EOL> if ircutils . isUserHostmask ( item ) : <EOL> name = ircutils . nickFromHostmask ( item ) <EOL> self . nicksToHostmasks [ name ] = name <EOL> else : <EOL> name = item <EOL> c . addUser ( name ) <EOL> if type == '<STR_LIT:@>' : <EOL> c . modes [ '<STR_LIT:s>' ] = None <EOL> def doChghost ( self , irc , msg ) : <EOL> ( user , host ) = msg . args <EOL> nick = msg . nick <EOL> hostmask = '<STR_LIT>' % ( nick , user , host ) <EOL> self . nicksToHostmasks [ nick ] = hostmask <EOL> def doJoin ( self , irc , msg ) : <EOL> for channel in msg . args [ <NUM_LIT:0> ] . split ( '<STR_LIT:U+002C>' ) : <EOL> if channel in self . channels : <EOL> self . channels [ channel ] . addUser ( msg . nick ) <EOL> elif msg . nick : <EOL> chan = ChannelState ( ) <EOL> chan . addUser ( msg . nick ) <EOL> self . channels [ channel ] = chan <EOL> def do367 ( self , irc , msg ) : <EOL> try : <EOL> state = self . channels [ msg . args [ <NUM_LIT:1> ] ] <EOL> except KeyError : <EOL> pass <EOL> else : <EOL> state . bans . add ( msg . args [ <NUM_LIT:2> ] ) <EOL> def doMode ( self , irc , msg ) : <EOL> channel = msg . args [ <NUM_LIT:0> ] <EOL> if ircutils . isChannel ( channel ) : <EOL> try : <EOL> chan = self . channels [ channel ] <EOL> except KeyError : <EOL> chan = ChannelState ( ) <EOL> self . channels [ channel ] = chan <EOL> chan . doMode ( msg ) <EOL> def do324 ( self , irc , msg ) : <EOL> channel = msg . args [ <NUM_LIT:1> ] <EOL> try : <EOL> chan = self . channels [ channel ] <EOL> except KeyError : <EOL> chan = ChannelState ( ) <EOL> self . channels [ channel ] = chan <EOL> for ( mode , value ) in ircutils . separateModes ( msg . args [ <NUM_LIT:2> : ] ) : <EOL> modeChar = mode [ <NUM_LIT:1> ] <EOL> if mode [ <NUM_LIT:0> ] == '<STR_LIT:+>' and mode [ <NUM_LIT:1> ] not in '<STR_LIT>' : <EOL> chan . setMode ( modeChar , value ) <EOL> elif mode [ <NUM_LIT:0> ] == '<STR_LIT:->' and mode [ <NUM_LIT:1> ] not in '<STR_LIT>' : <EOL> chan . unsetMode ( modeChar ) <EOL> def do329 ( self , irc , msg ) : <EOL> channel = msg . args [ <NUM_LIT:1> ] <EOL> try : <EOL> chan = self . channels [ channel ] <EOL> except KeyError : <EOL> chan = ChannelState ( ) <EOL> self . channels [ channel ] = chan <EOL> chan . created = int ( msg . args [ <NUM_LIT:2> ] ) <EOL> def doPart ( self , irc , msg ) : <EOL> for channel in msg . args [ <NUM_LIT:0> ] . split ( '<STR_LIT:U+002C>' ) : <EOL> try : <EOL> chan = self . channels [ channel ] <EOL> except KeyError : <EOL> continue <EOL> if ircutils . strEqual ( msg . nick , irc . nick ) : <EOL> del self . channels [ channel ] <EOL> else : <EOL> chan . removeUser ( msg . nick ) <EOL> def doKick ( self , irc , msg ) : <EOL> ( channel , users ) = msg . args [ : <NUM_LIT:2> ] <EOL> chan = self . channels [ channel ] <EOL> for user in users . split ( '<STR_LIT:U+002C>' ) : <EOL> if ircutils . strEqual ( user , irc . nick ) : <EOL> del self . channels [ channel ] <EOL> return <EOL> else : <EOL> chan . removeUser ( user ) <EOL> def doQuit ( self , irc , msg ) : <EOL> channel_names = ircutils . IrcSet ( ) <EOL> for ( name , channel ) in self . channels . items ( ) : <EOL> if msg . nick in channel . users : <EOL> channel_names . add ( name ) <EOL> channel . removeUser ( msg . nick ) <EOL> msg . tag ( '<STR_LIT>' , channel_names ) <EOL> if msg . nick in self . nicksToHostmasks : <EOL> del self . nicksToHostmasks [ msg . nick ] <EOL> def doTopic ( self , irc , msg ) : <EOL> if len ( msg . args ) == <NUM_LIT:1> : <EOL> return <EOL> try : <EOL> chan = self . channels [ msg . args [ <NUM_LIT:0> ] ] <EOL> chan . topic = msg . args [ <NUM_LIT:1> ] <EOL> except KeyError : <EOL> pass <EOL> def do332 ( self , irc , msg ) : <EOL> chan = self . channels [ msg . args [ <NUM_LIT:1> ] ] <EOL> chan . topic = msg . args [ <NUM_LIT:2> ] <EOL> def doNick ( self , irc , msg ) : <EOL> newNick = msg . args [ <NUM_LIT:0> ] <EOL> oldNick = msg . nick <EOL> try : <EOL> if msg . user and msg . host : <EOL> newHostmask = ircutils . joinHostmask ( newNick , msg . user , msg . host ) <EOL> self . nicksToHostmasks [ newNick ] = newHostmask <EOL> del self . nicksToHostmasks [ oldNick ] <EOL> except KeyError : <EOL> pass <EOL> channel_names = ircutils . IrcSet ( ) <EOL> for ( name , channel ) in self . channels . items ( ) : <EOL> if msg . nick in channel . users : <EOL> channel_names . add ( name ) <EOL> channel . replaceUser ( oldNick , newNick ) <EOL> msg . tag ( '<STR_LIT>' , channel_names ) <EOL> def doBatch ( self , irc , msg ) : <EOL> batch_name = msg . args [ <NUM_LIT:0> ] [ <NUM_LIT:1> : ] <EOL> if msg . args [ <NUM_LIT:0> ] . startswith ( '<STR_LIT:+>' ) : <EOL> batch_type = msg . args [ <NUM_LIT:1> ] <EOL> batch_arguments = tuple ( msg . args [ <NUM_LIT:2> : ] ) <EOL> self . batches [ batch_name ] = Batch ( type = batch_type , <EOL> arguments = batch_arguments , messages = [ ] ) <EOL> elif msg . args [ <NUM_LIT:0> ] . startswith ( '<STR_LIT:->' ) : <EOL> batch = self . batches . pop ( batch_name ) <EOL> msg . tag ( '<STR_LIT>' , batch ) <EOL> else : <EOL> assert False , msg . args [ <NUM_LIT:0> ] <EOL> def doAway ( self , irc , msg ) : <EOL> channel_names = ircutils . IrcSet ( ) <EOL> for ( name , channel ) in self . channels . items ( ) : <EOL> if msg . nick in channel . users : <EOL> channel_names . add ( name ) <EOL> msg . tag ( '<STR_LIT>' , channel_names ) <EOL> _callbacks = [ ] <EOL> class Irc ( IrcCommandDispatcher , log . Firewalled ) : <EOL> """<STR_LIT>""" <EOL> __firewalled__ = { '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , } <EOL> _nickSetters = set ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def __init__ ( self , network , callbacks = _callbacks ) : <EOL> self . zombie = False <EOL> world . ircs . append ( self ) <EOL> self . network = network <EOL> self . startedAt = time . time ( ) <EOL> self . callbacks = callbacks <EOL> self . state = IrcState ( ) <EOL> self . queue = IrcMsgQueue ( ) <EOL> self . fastqueue = smallqueue ( ) <EOL> self . driver = None <EOL> self . _setNonResettingVariables ( ) <EOL> self . _queueConnectMessages ( ) <EOL> self . startedSync = ircutils . IrcDict ( ) <EOL> self . monitoring = ircutils . IrcDict ( ) <EOL> def isChannel ( self , s ) : <EOL> """<STR_LIT>""" <EOL> kw = { } <EOL> if '<STR_LIT>' in self . state . supported : <EOL> kw [ '<STR_LIT>' ] = self . state . supported [ '<STR_LIT>' ] <EOL> if '<STR_LIT>' in self . state . supported : <EOL> kw [ '<STR_LIT>' ] = self . state . supported [ '<STR_LIT>' ] <EOL> return ircutils . isChannel ( s , ** kw ) <EOL> def isNick ( self , s ) : <EOL> kw = { } <EOL> if '<STR_LIT>' in self . state . supported : <EOL> kw [ '<STR_LIT>' ] = self . state . supported [ '<STR_LIT>' ] <EOL> return ircutils . isNick ( s , ** kw ) <EOL> def addCallback ( self , callback ) : <EOL> """<STR_LIT>""" <EOL> assert not self . getCallback ( callback . name ( ) ) <EOL> self . callbacks . append ( callback ) <EOL> cbs = [ ] <EOL> edges = set ( ) <EOL> for cb in self . callbacks : <EOL> ( before , after ) = cb . callPrecedence ( self ) <EOL> assert cb not in after , '<STR_LIT>' <EOL> assert cb not in before , '<STR_LIT>' <EOL> for otherCb in before : <EOL> edges . add ( ( otherCb , cb ) ) <EOL> for otherCb in after : <EOL> edges . add ( ( cb , otherCb ) ) <EOL> def getFirsts ( ) : <EOL> firsts = set ( self . callbacks ) - set ( cbs ) <EOL> for ( before , after ) in edges : <EOL> firsts . discard ( after ) <EOL> return firsts <EOL> firsts = getFirsts ( ) <EOL> while firsts : <EOL> for cb in firsts : <EOL> cbs . append ( cb ) <EOL> edgesToRemove = [ ] <EOL> for edge in edges : <EOL> if edge [ <NUM_LIT:0> ] is cb : <EOL> edgesToRemove . append ( edge ) <EOL> for edge in edgesToRemove : <EOL> edges . remove ( edge ) <EOL> firsts = getFirsts ( ) <EOL> assert len ( cbs ) == len ( self . callbacks ) , '<STR_LIT>' % ( cbs , self . callbacks ) <EOL> self . callbacks [ : ] = cbs <EOL> def getCallback ( self , name ) : <EOL> """<STR_LIT>""" <EOL> name = name . lower ( ) <EOL> for callback in self . callbacks : <EOL> if callback . name ( ) . lower ( ) == name : <EOL> return callback <EOL> else : <EOL> return None <EOL> def removeCallback ( self , name ) : <EOL> """<STR_LIT>""" <EOL> name = name . lower ( ) <EOL> def nameMatches ( cb ) : <EOL> return cb . name ( ) . lower ( ) == name <EOL> ( bad , good ) = utils . iter . partition ( nameMatches , self . callbacks ) <EOL> self . callbacks [ : ] = good <EOL> return bad <EOL> def queueMsg ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> if not self . zombie : <EOL> return self . queue . enqueue ( msg ) <EOL> else : <EOL> log . warning ( '<STR_LIT>' , msg , self ) <EOL> return False <EOL> def sendMsg ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> if not self . zombie : <EOL> self . fastqueue . enqueue ( msg ) <EOL> else : <EOL> log . warning ( '<STR_LIT>' , msg , self ) <EOL> def takeMsg ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . callbacks : <EOL> log . critical ( '<STR_LIT>' , self ) <EOL> now = time . time ( ) <EOL> msg = None <EOL> if self . fastqueue : <EOL> msg = self . fastqueue . dequeue ( ) <EOL> elif self . queue : <EOL> if now - self . lastTake <= conf . supybot . protocols . irc . throttleTime ( ) : <EOL> log . debug ( '<STR_LIT>' ) <EOL> else : <EOL> self . lastTake = now <EOL> msg = self . queue . dequeue ( ) <EOL> elif self . afterConnect and conf . supybot . protocols . irc . ping ( ) and now > self . lastping + conf . supybot . protocols . irc . ping . interval ( ) : <EOL> if self . outstandingPing : <EOL> s = '<STR_LIT>' % log . timestamp ( self . lastping ) <EOL> log . warning ( s ) <EOL> self . feedMsg ( ircmsgs . error ( s ) ) <EOL> self . driver . reconnect ( ) <EOL> elif not self . zombie : <EOL> self . lastping = now <EOL> now = str ( int ( now ) ) <EOL> self . outstandingPing = True <EOL> self . queueMsg ( ircmsgs . ping ( now ) ) <EOL> if msg : <EOL> for callback in reversed ( self . callbacks ) : <EOL> msg = callback . outFilter ( self , msg ) <EOL> if msg is None : <EOL> log . debug ( '<STR_LIT>' , callback . name ( ) ) <EOL> return self . takeMsg ( ) <EOL> world . debugFlush ( ) <EOL> if len ( str ( msg ) ) > <NUM_LIT> : <EOL> log . debug ( '<STR_LIT>' , msg ) <EOL> msg . _str = msg . _str [ : <NUM_LIT> ] + '<STR_LIT:\r\n>' <EOL> msg . _len = len ( str ( msg ) ) <EOL> if world . testing : <EOL> self . state . addMsg ( self , msg ) <EOL> log . debug ( '<STR_LIT>' , self . network , str ( msg ) . rstrip ( '<STR_LIT:\r\n>' ) ) <EOL> return msg <EOL> elif self . zombie : <EOL> self . driver . die ( ) <EOL> self . _reallyDie ( ) <EOL> else : <EOL> return None <EOL> _numericErrorCommandRe = re . compile ( r'<STR_LIT>' ) <EOL> def feedMsg ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> msg . tag ( '<STR_LIT>' , self ) <EOL> msg . tag ( '<STR_LIT>' , self . network ) <EOL> msg . tag ( '<STR_LIT>' , time . time ( ) ) <EOL> if msg . args and self . isChannel ( msg . args [ <NUM_LIT:0> ] ) : <EOL> channel = msg . args [ <NUM_LIT:0> ] <EOL> else : <EOL> channel = None <EOL> preInFilter = str ( msg ) . rstrip ( '<STR_LIT:\r\n>' ) <EOL> log . debug ( '<STR_LIT>' , self . network , preInFilter ) <EOL> if msg . prefix == self . nick : <EOL> log . debug ( '<STR_LIT>' ) <EOL> msg = ircmsgs . IrcMsg ( prefix = self . prefix , msg = msg ) <EOL> if msg . nick == self . nick and self . prefix != msg . prefix : <EOL> self . prefix = msg . prefix <EOL> if msg . command in self . _nickSetters : <EOL> if msg . args [ <NUM_LIT:0> ] != self . nick : <EOL> self . nick = msg . args [ <NUM_LIT:0> ] <EOL> log . debug ( '<STR_LIT>' , self . nick ) <EOL> if msg . prefix != self . server : <EOL> self . server = msg . prefix <EOL> log . debug ( '<STR_LIT>' , self . server ) <EOL> method = self . dispatchCommand ( msg . command ) <EOL> if method is not None : <EOL> method ( msg ) <EOL> elif self . _numericErrorCommandRe . search ( msg . command ) : <EOL> log . error ( '<STR_LIT>' % msg ) <EOL> try : <EOL> self . state . addMsg ( self , msg ) <EOL> except : <EOL> log . exception ( '<STR_LIT>' ) <EOL> world . debugFlush ( ) <EOL> for callback in self . callbacks : <EOL> try : <EOL> m = callback . inFilter ( self , msg ) <EOL> if not m : <EOL> log . debug ( '<STR_LIT>' , callback . name ( ) ) <EOL> return <EOL> msg = m <EOL> except : <EOL> log . exception ( '<STR_LIT>' ) <EOL> world . debugFlush ( ) <EOL> postInFilter = str ( msg ) . rstrip ( '<STR_LIT:\r\n>' ) <EOL> if postInFilter != preInFilter : <EOL> log . debug ( '<STR_LIT>' , postInFilter ) <EOL> for callback in self . callbacks : <EOL> try : <EOL> if callback is not None : <EOL> callback ( self , msg ) <EOL> except : <EOL> log . exception ( '<STR_LIT>' ) <EOL> world . debugFlush ( ) <EOL> def die ( self ) : <EOL> """<STR_LIT>""" <EOL> self . zombie = True <EOL> if not self . afterConnect : <EOL> self . _reallyDie ( ) <EOL> def reset ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _setNonResettingVariables ( ) <EOL> self . state . reset ( ) <EOL> self . queue . reset ( ) <EOL> self . fastqueue . reset ( ) <EOL> self . startedSync . clear ( ) <EOL> for callback in self . callbacks : <EOL> callback . reset ( ) <EOL> self . _queueConnectMessages ( ) <EOL> def _setNonResettingVariables ( self ) : <EOL> network_config = conf . supybot . networks . get ( self . network ) <EOL> def get_value ( name ) : <EOL> return getattr ( network_config , name ) ( ) or getattr ( conf . supybot , name ) ( ) <EOL> self . nick = get_value ( '<STR_LIT>' ) <EOL> self . user = get_value ( '<STR_LIT:user>' ) <EOL> self . ident = get_value ( '<STR_LIT>' ) <EOL> self . alternateNicks = conf . supybot . nick . alternates ( ) [ : ] <EOL> self . password = network_config . password ( ) <EOL> self . prefix = '<STR_LIT>' % ( self . nick , self . ident , '<STR_LIT>' ) <EOL> self . lastTake = <NUM_LIT:0> <EOL> self . server = '<STR_LIT>' <EOL> self . afterConnect = False <EOL> self . startedAt = time . time ( ) <EOL> self . lastping = time . time ( ) <EOL> self . outstandingPing = False <EOL> self . capNegociationEnded = False <EOL> self . requireStarttls = not network_config . ssl ( ) and network_config . requireStarttls ( ) <EOL> self . resetSasl ( ) <EOL> def resetSasl ( self ) : <EOL> network_config = conf . supybot . networks . get ( self . network ) <EOL> self . sasl_authenticated = False <EOL> self . sasl_username = network_config . sasl . username ( ) <EOL> self . sasl_password = network_config . sasl . password ( ) <EOL> self . sasl_ecdsa_key = network_config . sasl . ecdsa_key ( ) <EOL> self . authenticate_decoder = None <EOL> self . sasl_next_mechanisms = [ ] <EOL> self . sasl_current_mechanism = None <EOL> for mechanism in network_config . sasl . mechanisms ( ) : <EOL> if mechanism == '<STR_LIT>' and ecdsa and self . sasl_username and self . sasl_ecdsa_key : <EOL> self . sasl_next_mechanisms . append ( mechanism ) <EOL> elif mechanism == '<STR_LIT>' and ( <EOL> network_config . certfile ( ) or <EOL> conf . supybot . protocols . irc . certfile ( ) ) : <EOL> self . sasl_next_mechanisms . append ( mechanism ) <EOL> elif mechanism == '<STR_LIT>' and self . sasl_username and self . sasl_password : <EOL> self . sasl_next_mechanisms . append ( mechanism ) <EOL> if self . sasl_next_mechanisms : <EOL> self . REQUEST_CAPABILITIES . add ( '<STR_LIT>' ) <EOL> REQUEST_CAPABILITIES = set ( [ '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def _queueConnectMessages ( self ) : <EOL> if self . zombie : <EOL> self . driver . die ( ) <EOL> self . _reallyDie ( ) <EOL> return <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , args = ( '<STR_LIT>' , '<STR_LIT>' ) ) ) <EOL> if self . requireStarttls : <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' ) ) <EOL> else : <EOL> self . sendAuthenticationMessages ( ) <EOL> def do670 ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> log . info ( '<STR_LIT>' , self . network ) <EOL> self . requireStarttls = False <EOL> self . driver . starttls ( ) <EOL> self . sendAuthenticationMessages ( ) <EOL> def do691 ( self , irc , msg ) : <EOL> """<STR_LIT>""" <EOL> log . error ( '<STR_LIT>' , self . network , msg . args [ <NUM_LIT:0> ] ) <EOL> self . feedMsg ( ircmsgs . error ( '<STR_LIT>' ) ) <EOL> self . driver . reconnect ( ) <EOL> def sendAuthenticationMessages ( self ) : <EOL> if self . password : <EOL> log . info ( '<STR_LIT>' , <EOL> self . network ) <EOL> self . sendMsg ( ircmsgs . password ( self . password ) ) <EOL> log . debug ( '<STR_LIT>' , <EOL> self . network , self . nick ) <EOL> self . sendMsg ( ircmsgs . nick ( self . nick ) ) <EOL> log . debug ( '<STR_LIT>' , <EOL> self . network , self . ident , self . user ) <EOL> self . sendMsg ( ircmsgs . user ( self . ident , self . user ) ) <EOL> def endCapabilityNegociation ( self ) : <EOL> if not self . capNegociationEnded : <EOL> self . capNegociationEnded = True <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , args = ( '<STR_LIT>' , ) ) ) <EOL> def sendSaslString ( self , string ) : <EOL> for chunk in ircutils . authenticate_generator ( string ) : <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , <EOL> args = ( chunk , ) ) ) <EOL> def tryNextSaslMechanism ( self ) : <EOL> if self . sasl_next_mechanisms : <EOL> self . sasl_current_mechanism = self . sasl_next_mechanisms . pop ( <NUM_LIT:0> ) <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , <EOL> args = ( self . sasl_current_mechanism . upper ( ) , ) ) ) <EOL> else : <EOL> self . sasl_current_mechanism = None <EOL> self . endCapabilityNegociation ( ) <EOL> def filterSaslMechanisms ( self , available ) : <EOL> available = set ( map ( str . lower , available ) ) <EOL> self . sasl_next_mechanisms = [ <EOL> x for x in self . sasl_next_mechanisms <EOL> if x . lower ( ) in available ] <EOL> def doAuthenticate ( self , msg ) : <EOL> if not self . authenticate_decoder : <EOL> self . authenticate_decoder = ircutils . AuthenticateDecoder ( ) <EOL> self . authenticate_decoder . feed ( msg ) <EOL> if not self . authenticate_decoder . ready : <EOL> return <EOL> string = self . authenticate_decoder . get ( ) <EOL> self . authenticate_decoder = None <EOL> mechanism = self . sasl_current_mechanism <EOL> if mechanism == '<STR_LIT>' : <EOL> if string == b'<STR_LIT>' : <EOL> self . sendSaslString ( self . sasl_username . encode ( '<STR_LIT:utf-8>' ) ) <EOL> return <EOL> try : <EOL> with open ( self . sasl_ecdsa_key ) as fd : <EOL> private_key = SigningKey . from_pem ( fd . read ( ) ) <EOL> authstring = private_key . sign ( base64 . b64decode ( msg . args [ <NUM_LIT:0> ] . encode ( ) ) ) <EOL> self . sendSaslString ( authstring ) <EOL> except ( BadDigestError , OSError , ValueError ) : <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , <EOL> args = ( '<STR_LIT:*>' , ) ) ) <EOL> self . tryNextSaslMechanism ( ) <EOL> elif mechanism == '<STR_LIT>' : <EOL> self . sendSaslString ( b'<STR_LIT>' ) <EOL> elif mechanism == '<STR_LIT>' : <EOL> authstring = b'<STR_LIT>' . join ( [ <EOL> self . sasl_username . encode ( '<STR_LIT:utf-8>' ) , <EOL> self . sasl_username . encode ( '<STR_LIT:utf-8>' ) , <EOL> self . sasl_password . encode ( '<STR_LIT:utf-8>' ) , <EOL> ] ) <EOL> self . sendSaslString ( authstring ) <EOL> def do903 ( self , msg ) : <EOL> log . info ( '<STR_LIT>' , self . network ) <EOL> self . sasl_authenticated = True <EOL> self . endCapabilityNegociation ( ) <EOL> def do904 ( self , msg ) : <EOL> log . warning ( '<STR_LIT>' , self . network ) <EOL> self . tryNextSaslMechanism ( ) <EOL> def do905 ( self , msg ) : <EOL> log . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' , self . network ) <EOL> self . tryNextSaslMechanism ( ) <EOL> def do906 ( self , msg ) : <EOL> log . warning ( '<STR_LIT>' , self . network ) <EOL> self . tryNextSaslMechanism ( ) <EOL> def do907 ( self , msg ) : <EOL> log . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' , self . network ) <EOL> self . tryNextSaslMechanism ( ) <EOL> def do908 ( self , msg ) : <EOL> log . info ( '<STR_LIT>' , <EOL> self . network , msg . args [ <NUM_LIT:1> ] ) <EOL> self . filterSaslMechanisms ( set ( msg . args [ <NUM_LIT:1> ] . split ( '<STR_LIT:U+002C>' ) ) ) <EOL> def doCap ( self , msg ) : <EOL> subcommand = msg . args [ <NUM_LIT:1> ] <EOL> if subcommand == '<STR_LIT>' : <EOL> self . doCapAck ( msg ) <EOL> elif subcommand == '<STR_LIT>' : <EOL> self . doCapNak ( msg ) <EOL> elif subcommand == '<STR_LIT>' : <EOL> self . doCapLs ( msg ) <EOL> elif subcommand == '<STR_LIT>' : <EOL> self . doCapDel ( msg ) <EOL> elif subcommand == '<STR_LIT>' : <EOL> self . doCapNew ( msg ) <EOL> def doCapAck ( self , msg ) : <EOL> if len ( msg . args ) != <NUM_LIT:3> : <EOL> log . warning ( '<STR_LIT>' , msg ) <EOL> return <EOL> caps = msg . args [ <NUM_LIT:2> ] . split ( ) <EOL> assert caps , '<STR_LIT>' <EOL> log . debug ( '<STR_LIT>' , <EOL> self . network , caps ) <EOL> self . state . capabilities_ack . update ( caps ) <EOL> if '<STR_LIT>' in caps : <EOL> self . tryNextSaslMechanism ( ) <EOL> else : <EOL> self . endCapabilityNegociation ( ) <EOL> def doCapNak ( self , msg ) : <EOL> if len ( msg . args ) != <NUM_LIT:3> : <EOL> log . warning ( '<STR_LIT>' , msg ) <EOL> return <EOL> caps = msg . args [ <NUM_LIT:2> ] . split ( ) <EOL> assert caps , '<STR_LIT>' <EOL> self . state . capabilities_nak . update ( caps ) <EOL> log . warning ( '<STR_LIT>' , <EOL> self . network , caps ) <EOL> self . endCapabilityNegociation ( ) <EOL> def _addCapabilities ( self , capstring ) : <EOL> for item in capstring . split ( ) : <EOL> while item . startswith ( ( '<STR_LIT:=>' , '<STR_LIT>' ) ) : <EOL> item = item [ <NUM_LIT:1> : ] <EOL> if '<STR_LIT:=>' in item : <EOL> ( cap , value ) = item . split ( '<STR_LIT:=>' , <NUM_LIT:1> ) <EOL> self . state . capabilities_ls [ cap ] = value <EOL> else : <EOL> self . state . capabilities_ls [ item ] = None <EOL> def doCapLs ( self , msg ) : <EOL> if len ( msg . args ) == <NUM_LIT:4> : <EOL> if msg . args [ <NUM_LIT:2> ] != '<STR_LIT:*>' : <EOL> log . warning ( '<STR_LIT>' , msg ) <EOL> return <EOL> self . _addCapabilities ( msg . args [ <NUM_LIT:3> ] ) <EOL> elif len ( msg . args ) == <NUM_LIT:3> : <EOL> self . _addCapabilities ( msg . args [ <NUM_LIT:2> ] ) <EOL> common_supported_capabilities = set ( self . state . capabilities_ls ) & self . REQUEST_CAPABILITIES <EOL> if '<STR_LIT>' in self . state . capabilities_ls : <EOL> s = self . state . capabilities_ls [ '<STR_LIT>' ] <EOL> if s is not None : <EOL> self . filterSaslMechanisms ( set ( s . split ( '<STR_LIT:U+002C>' ) ) ) <EOL> if '<STR_LIT>' not in self . state . capabilities_ls and self . requireStarttls : <EOL> log . error ( '<STR_LIT>' , self . network ) <EOL> self . feedMsg ( ircmsgs . error ( '<STR_LIT>' <EOL> '<STR_LIT>' ) ) <EOL> self . die ( ) <EOL> return <EOL> if common_supported_capabilities : <EOL> caps = '<STR_LIT:U+0020>' . join ( sorted ( common_supported_capabilities ) ) <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , <EOL> args = ( '<STR_LIT>' , caps ) ) ) <EOL> else : <EOL> self . endCapabilityNegociation ( ) <EOL> else : <EOL> log . warning ( '<STR_LIT>' , msg ) <EOL> return <EOL> def doCapDel ( self , msg ) : <EOL> if len ( msg . args ) != <NUM_LIT:3> : <EOL> log . warning ( '<STR_LIT>' , msg ) <EOL> return <EOL> caps = msg . args [ <NUM_LIT:2> ] . split ( ) <EOL> assert caps , '<STR_LIT>' <EOL> for cap in caps : <EOL> cap = cap . split ( '<STR_LIT:=>' ) [ <NUM_LIT:0> ] <EOL> try : <EOL> del self . state . capabilities_ls [ cap ] <EOL> except KeyError : <EOL> pass <EOL> try : <EOL> self . state . capabilities_ack . remove ( cap ) <EOL> except KeyError : <EOL> pass <EOL> def doCapNew ( self , msg ) : <EOL> if len ( msg . args ) != <NUM_LIT:3> : <EOL> log . warning ( '<STR_LIT>' , msg ) <EOL> return <EOL> caps = msg . args [ <NUM_LIT:2> ] . split ( ) <EOL> assert caps , '<STR_LIT>' <EOL> self . _addCapabilities ( msg . args [ <NUM_LIT:2> ] ) <EOL> if not self . sasl_authenticated and '<STR_LIT>' in self . state . capabilities_ls : <EOL> self . resetSasl ( ) <EOL> s = self . state . capabilities_ls [ '<STR_LIT>' ] <EOL> if s is not None : <EOL> self . filterSaslMechanisms ( set ( s . split ( '<STR_LIT:U+002C>' ) ) ) <EOL> common_supported_unrequested_capabilities = ( <EOL> set ( self . state . capabilities_ls ) & <EOL> self . REQUEST_CAPABILITIES - <EOL> self . state . capabilities_ack ) <EOL> if common_supported_unrequested_capabilities : <EOL> caps = '<STR_LIT:U+0020>' . join ( sorted ( common_supported_unrequested_capabilities ) ) <EOL> self . sendMsg ( ircmsgs . IrcMsg ( command = '<STR_LIT>' , <EOL> args = ( '<STR_LIT>' , caps ) ) ) <EOL> def monitor ( self , targets ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( targets , str ) : <EOL> targets = [ targets ] <EOL> not_yet_monitored = set ( ) <EOL> for target in targets : <EOL> if target in self . monitoring : <EOL> self . monitoring [ target ] += <NUM_LIT:1> <EOL> else : <EOL> not_yet_monitored . add ( target ) <EOL> self . monitoring [ target ] = <NUM_LIT:1> <EOL> if not_yet_monitored : <EOL> self . queueMsg ( ircmsgs . monitor ( '<STR_LIT:+>' , not_yet_monitored ) ) <EOL> return not_yet_monitored <EOL> def unmonitor ( self , targets ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( targets , str ) : <EOL> targets = [ targets ] <EOL> should_be_unmonitored = set ( ) <EOL> for target in targets : <EOL> self . monitoring [ target ] -= <NUM_LIT:1> <EOL> if self . monitoring [ target ] == <NUM_LIT:0> : <EOL> del self . monitoring [ target ] <EOL> should_be_unmonitored . add ( target ) <EOL> if should_be_unmonitored : <EOL> self . queueMsg ( ircmsgs . monitor ( '<STR_LIT:->' , should_be_unmonitored ) ) <EOL> return should_be_unmonitored <EOL> def _getNextNick ( self ) : <EOL> if self . alternateNicks : <EOL> nick = self . alternateNicks . pop ( <NUM_LIT:0> ) <EOL> if '<STR_LIT:%s>' in nick : <EOL> network_nick = conf . supybot . networks . get ( self . network ) . nick ( ) <EOL> if network_nick == '<STR_LIT>' : <EOL> nick %= conf . supybot . nick ( ) <EOL> else : <EOL> nick %= network_nick <EOL> return nick <EOL> else : <EOL> nick = conf . supybot . nick ( ) <EOL> network_nick = conf . supybot . networks . get ( self . network ) . nick ( ) <EOL> if network_nick != '<STR_LIT>' : <EOL> nick = network_nick <EOL> ret = nick <EOL> L = list ( nick ) <EOL> while len ( L ) <= <NUM_LIT:3> : <EOL> L . append ( '<STR_LIT>' ) <EOL> while ircutils . strEqual ( ret , nick ) : <EOL> L [ random . randrange ( len ( L ) ) ] = utils . iter . choice ( '<STR_LIT>' ) <EOL> ret = '<STR_LIT>' . join ( L ) <EOL> return ret <EOL> def do002 ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> ( beginning , version ) = rsplit ( msg . args [ - <NUM_LIT:1> ] , maxsplit = <NUM_LIT:1> ) <EOL> log . info ( '<STR_LIT>' , self . server , version ) <EOL> def doPing ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> self . sendMsg ( ircmsgs . pong ( msg . args [ <NUM_LIT:0> ] ) ) <EOL> def doPong ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> self . outstandingPing = False <EOL> def do376 ( self , msg ) : <EOL> log . info ( '<STR_LIT>' , self . server ) <EOL> self . afterConnect = True <EOL> self . alternateNicks = conf . supybot . nick . alternates ( ) [ : ] <EOL> umodes = conf . supybot . networks . get ( self . network ) . umodes ( ) <EOL> if umodes == '<STR_LIT>' : <EOL> umodes = conf . supybot . protocols . irc . umodes ( ) <EOL> supported = self . state . supported . get ( '<STR_LIT>' ) <EOL> if supported : <EOL> acceptedchars = supported . union ( '<STR_LIT>' ) <EOL> umodes = '<STR_LIT>' . join ( [ m for m in umodes if m in acceptedchars ] ) <EOL> if umodes : <EOL> log . info ( '<STR_LIT>' , self . network , umodes ) <EOL> self . sendMsg ( ircmsgs . mode ( self . nick , umodes ) ) <EOL> do377 = do422 = do376 <EOL> def do43x ( self , msg , problem ) : <EOL> if not self . afterConnect : <EOL> newNick = self . _getNextNick ( ) <EOL> assert newNick != self . nick <EOL> log . info ( '<STR_LIT>' , <EOL> msg . command , self . nick , problem , newNick ) <EOL> self . sendMsg ( ircmsgs . nick ( newNick ) ) <EOL> def do437 ( self , msg ) : <EOL> self . do43x ( msg , '<STR_LIT>' ) <EOL> def do433 ( self , msg ) : <EOL> self . do43x ( msg , '<STR_LIT>' ) <EOL> def do432 ( self , msg ) : <EOL> self . do43x ( msg , '<STR_LIT>' ) <EOL> def doJoin ( self , msg ) : <EOL> if msg . nick == self . nick : <EOL> channel = msg . args [ <NUM_LIT:0> ] <EOL> self . queueMsg ( ircmsgs . who ( channel , args = ( '<STR_LIT>' , ) ) ) <EOL> self . queueMsg ( ircmsgs . mode ( channel ) ) <EOL> for channel in msg . args [ <NUM_LIT:0> ] . split ( '<STR_LIT:U+002C>' ) : <EOL> self . queueMsg ( ircmsgs . mode ( channel , '<STR_LIT>' ) ) <EOL> self . startedSync [ channel ] = time . time ( ) <EOL> def do315 ( self , msg ) : <EOL> channel = msg . args [ <NUM_LIT:1> ] <EOL> if channel in self . startedSync : <EOL> now = time . time ( ) <EOL> started = self . startedSync . pop ( channel ) <EOL> elapsed = now - started <EOL> log . info ( '<STR_LIT>' , <EOL> channel , self . network , elapsed ) <EOL> def doError ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> log . warning ( '<STR_LIT>' , self . network , msg . args [ <NUM_LIT:0> ] ) <EOL> if not self . zombie : <EOL> if msg . args [ <NUM_LIT:0> ] . lower ( ) . startswith ( '<STR_LIT>' ) : <EOL> self . driver . reconnect ( ) <EOL> elif '<STR_LIT>' in msg . args [ <NUM_LIT:0> ] : <EOL> self . driver . reconnect ( wait = True ) <EOL> def doNick ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> if msg . nick == self . nick : <EOL> newNick = msg . args [ <NUM_LIT:0> ] <EOL> self . nick = newNick <EOL> ( nick , user , domain ) = ircutils . splitHostmask ( msg . prefix ) <EOL> self . prefix = ircutils . joinHostmask ( self . nick , user , domain ) <EOL> elif conf . supybot . followIdentificationThroughNickChanges ( ) : <EOL> try : <EOL> id = ircdb . users . getUserId ( msg . prefix ) <EOL> u = ircdb . users . getUser ( id ) <EOL> except KeyError : <EOL> return <EOL> if u . auth : <EOL> ( _ , user , host ) = ircutils . splitHostmask ( msg . prefix ) <EOL> newhostmask = ircutils . joinHostmask ( msg . args [ <NUM_LIT:0> ] , user , host ) <EOL> for ( i , ( when , authmask ) ) in enumerate ( u . auth [ : ] ) : <EOL> if ircutils . strEqual ( msg . prefix , authmask ) : <EOL> log . info ( '<STR_LIT>' , <EOL> u . name , authmask , newhostmask ) <EOL> u . auth [ i ] = ( u . auth [ i ] [ <NUM_LIT:0> ] , newhostmask ) <EOL> ircdb . users . setUser ( u ) <EOL> def _reallyDie ( self ) : <EOL> """<STR_LIT>""" <EOL> log . info ( '<STR_LIT>' , self . network ) <EOL> if self . driver is not None and hasattr ( self . driver , '<STR_LIT>' ) : <EOL> self . driver . die ( ) <EOL> if self in world . ircs : <EOL> world . ircs . remove ( self ) <EOL> if not world . ircs : <EOL> for cb in self . callbacks : <EOL> cb . die ( ) <EOL> log . debug ( '<STR_LIT>' ) <EOL> self . callbacks [ : ] = [ ] <EOL> else : <EOL> log . warning ( '<STR_LIT>' , utils . stackTrace ( ) ) <EOL> def __hash__ ( self ) : <EOL> return id ( self ) <EOL> def __eq__ ( self , other ) : <EOL> if isinstance ( other , self . __class__ ) : <EOL> return id ( self ) == id ( other ) <EOL> else : <EOL> return other . __eq__ ( self ) <EOL> def __ne__ ( self , other ) : <EOL> return not ( self == other ) <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % self . network <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % self . network </s>
