mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-10-01 17:16:31 +02:00
Allow multiple nicks, refactored irclib.Irc a bit.
This commit is contained in:
parent
dc4d78774d
commit
7dbbf16dcc
@ -208,7 +208,6 @@ if __name__ == '__main__':
|
|||||||
defaultNetwork = conf.supybot.networks.default()
|
defaultNetwork = conf.supybot.networks.default()
|
||||||
network = conf.supybot.networks.get(defaultNetwork)
|
network = conf.supybot.networks.get(defaultNetwork)
|
||||||
server = network.server()
|
server = network.server()
|
||||||
password = network.password()
|
|
||||||
if ':' in server:
|
if ':' in server:
|
||||||
serverAndPort = server.split(':', 1)
|
serverAndPort = server.split(':', 1)
|
||||||
serverAndPort[1] = int(serverAndPort[1])
|
serverAndPort[1] = int(serverAndPort[1])
|
||||||
@ -251,8 +250,7 @@ if __name__ == '__main__':
|
|||||||
import supybot.callbacks as callbacks
|
import supybot.callbacks as callbacks
|
||||||
import supybot.Owner as Owner
|
import supybot.Owner as Owner
|
||||||
|
|
||||||
irc = irclib.Irc(nick, user=user, ident=ident,
|
irc = irclib.Irc(network=defaultNetwork)
|
||||||
network=defaultNetwork, password=password)
|
|
||||||
callback = Owner.Class()
|
callback = Owner.Class()
|
||||||
irc.addCallback(callback)
|
irc.addCallback(callback)
|
||||||
driver = drivers.newDriver(server, irc)
|
driver = drivers.newDriver(server, irc)
|
||||||
|
17
src/conf.py
17
src/conf.py
@ -129,6 +129,9 @@ class ValidNick(registry.String):
|
|||||||
else:
|
else:
|
||||||
registry.String.setValue(self, v)
|
registry.String.setValue(self, v)
|
||||||
|
|
||||||
|
class ValidNicks(registry.SpaceSeparatedListOf):
|
||||||
|
Value = ValidNick
|
||||||
|
|
||||||
class ValidChannel(registry.String):
|
class ValidChannel(registry.String):
|
||||||
"""Value must be a valid IRC channel name."""
|
"""Value must be a valid IRC channel name."""
|
||||||
def setValue(self, v):
|
def setValue(self, v):
|
||||||
@ -142,7 +145,12 @@ class ValidChannel(registry.String):
|
|||||||
registry.String.setValue(self, v)
|
registry.String.setValue(self, v)
|
||||||
|
|
||||||
registerGlobalValue(supybot, 'nick',
|
registerGlobalValue(supybot, 'nick',
|
||||||
ValidNick('supybot', """Determines the bot's nick."""))
|
ValidNick('supybot', """Determines the bot's default nick."""))
|
||||||
|
|
||||||
|
registerGlobalValue(supybot.nick, 'alternates', ValidNicks([], """Determines
|
||||||
|
what alternative nicks will be used if the primary nick (supybot.nick)
|
||||||
|
isn't available. If none are given, or if all are taken, the primary nick
|
||||||
|
will be perturbed appropriately until an unused nick is found."""))
|
||||||
|
|
||||||
registerGlobalValue(supybot, 'ident',
|
registerGlobalValue(supybot, 'ident',
|
||||||
ValidNick('supybot', """Determines the bot's ident string, if the server
|
ValidNick('supybot', """Determines the bot's ident string, if the server
|
||||||
@ -450,13 +458,6 @@ registerChannelValue(supybot.replies, 'possibleBug',
|
|||||||
# End supybot.replies.
|
# End supybot.replies.
|
||||||
###
|
###
|
||||||
|
|
||||||
# XXX: This should be SpaceSeparated, if it survives.
|
|
||||||
supybot.register('nickmods', registry.CommaSeparatedListOfStrings(
|
|
||||||
'__%s__,%s^,%s`,%s_,%s__,_%s,__%s,[%s]'.split(','),
|
|
||||||
"""A list of modifications to be made to a nick when the nick the bot tries
|
|
||||||
to get from the server is in use. There should be one %s in each string;
|
|
||||||
this will get replaced with the original nick."""))
|
|
||||||
|
|
||||||
registerGlobalValue(supybot, 'snarfThrottle',
|
registerGlobalValue(supybot, 'snarfThrottle',
|
||||||
registry.Float(10.0, """A floating point number of seconds to throttle
|
registry.Float(10.0, """A floating point number of seconds to throttle
|
||||||
snarfed URLs, in order to prevent loops between two bots snarfing the same
|
snarfed URLs, in order to prevent loops between two bots snarfing the same
|
||||||
|
104
src/irclib.py
104
src/irclib.py
@ -36,6 +36,7 @@ import supybot.fix as fix
|
|||||||
import copy
|
import copy
|
||||||
import sets
|
import sets
|
||||||
import time
|
import time
|
||||||
|
import operator
|
||||||
from itertools import imap, chain, cycle
|
from itertools import imap, chain, cycle
|
||||||
|
|
||||||
import supybot.log as log
|
import supybot.log as log
|
||||||
@ -332,7 +333,8 @@ class IrcState(IrcCommandDispatcher):
|
|||||||
chan = ChannelState()
|
chan = ChannelState()
|
||||||
chan.addUser(msg.nick)
|
chan.addUser(msg.nick)
|
||||||
self.channels[channel] = chan
|
self.channels[channel] = chan
|
||||||
assert msg.nick == irc.nick, msg
|
# I don't know why this assert was here.
|
||||||
|
#assert msg.nick == irc.nick, msg
|
||||||
|
|
||||||
def doMode(self, irc, msg):
|
def doMode(self, irc, msg):
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
@ -441,65 +443,86 @@ class Irc(IrcCommandDispatcher):
|
|||||||
_nickSetters = sets.Set(['001', '002', '003', '004', '250', '251', '252',
|
_nickSetters = sets.Set(['001', '002', '003', '004', '250', '251', '252',
|
||||||
'254', '255', '265', '266', '372', '375', '376',
|
'254', '255', '265', '266', '372', '375', '376',
|
||||||
'333', '353', '332', '366', '005'])
|
'333', '353', '332', '366', '005'])
|
||||||
def __init__(self, nick, user='', ident='',
|
def __init__(self, network, callbacks=None):
|
||||||
network='unset', password='', callbacks=None):
|
|
||||||
world.ircs.append(self)
|
world.ircs.append(self)
|
||||||
self.originalNick = intern(nick)
|
self.network = network
|
||||||
self.originalNetwork = intern(network)
|
|
||||||
self.nick = self.originalNick
|
|
||||||
self.network = self.originalNetwork
|
|
||||||
self.nickmods = cycle(conf.supybot.nickmods())
|
|
||||||
self.password = password
|
|
||||||
self.user = intern(user or nick) # Default to nick
|
|
||||||
self.ident = intern(ident or nick) # Ditto.
|
|
||||||
self.prefix = '%s!%s@%s' % (nick, ident, 'unset.domain')
|
|
||||||
if callbacks is None:
|
if callbacks is None:
|
||||||
self.callbacks = []
|
self.callbacks = []
|
||||||
else:
|
else:
|
||||||
self.callbacks = callbacks
|
self.callbacks = callbacks
|
||||||
self.state = IrcState()
|
self.state = IrcState()
|
||||||
self.queue = IrcMsgQueue()
|
self.queue = IrcMsgQueue()
|
||||||
self.lastTake = 0
|
|
||||||
self.server = 'unset'
|
|
||||||
self.afterConnect = False
|
|
||||||
self.fastqueue = smallqueue()
|
self.fastqueue = smallqueue()
|
||||||
self.lastping = time.time()
|
|
||||||
self.outstandingPing = False
|
|
||||||
self.driver = None # The driver should set this later.
|
self.driver = None # The driver should set this later.
|
||||||
if self.password:
|
self._setNonResettingVariables()
|
||||||
self.queue.enqueue(ircmsgs.password(self.password))
|
self._queueConnectMessages()
|
||||||
log.info('Sending NICK command, nick is %s.', self.nick)
|
|
||||||
self.queue.enqueue(ircmsgs.nick(self.nick))
|
|
||||||
log.info('Sending USER command, ident is %s, user is %s.',
|
|
||||||
self.nick, self.user)
|
|
||||||
self.queue.enqueue(ircmsgs.user(self.ident, self.user))
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Resets the Irc object. Called when the driver reconnects."""
|
"""Resets the Irc object. Called when the driver reconnects."""
|
||||||
self.nick = self.originalNick
|
self._setNonResettingVariables()
|
||||||
self.network = self.originalNetwork
|
self._queueConnectMessages()
|
||||||
self.prefix = '%s!%s@%s' % (self.nick, self.ident, 'unset.domain')
|
|
||||||
self.state.reset()
|
self.state.reset()
|
||||||
self.queue.reset()
|
self.queue.reset()
|
||||||
|
self.fastqueue.reset()
|
||||||
|
for callback in self.callbacks:
|
||||||
|
callback.reset()
|
||||||
|
|
||||||
|
def _setNonResettingVariables(self):
|
||||||
|
# Configuration stuff.
|
||||||
|
self.nick = conf.supybot.nick()
|
||||||
|
self.user = conf.supybot.user()
|
||||||
|
self.ident = conf.supybot.ident()
|
||||||
|
self.alternateNicks = conf.supybot.nick.alternates()[:]
|
||||||
|
self.password = conf.supybot.networks.get(self.network).password()
|
||||||
|
self.prefix = '%s!%s@%s' % (self.nick, self.ident, 'unset.domain')
|
||||||
|
# The rest.
|
||||||
|
self.lastTake = 0
|
||||||
self.server = 'unset'
|
self.server = 'unset'
|
||||||
self.afterConnect = False
|
self.afterConnect = False
|
||||||
self.lastping = time.time()
|
self.lastping = time.time()
|
||||||
self.outstandingPing = False
|
self.outstandingPing = False
|
||||||
self.fastqueue = queue()
|
|
||||||
|
def _queueConnectMessages(self):
|
||||||
if self.password:
|
if self.password:
|
||||||
self.queue.enqueue(ircmsgs.password(self.password))
|
log.info('Sending PASS command, not logging the password.')
|
||||||
self.queue.enqueue(ircmsgs.nick(self.nick))
|
self.queueMsg(ircmsgs.password(self.password))
|
||||||
self.queue.enqueue(ircmsgs.user(self.ident, self.user))
|
log.info('Sending NICK command, nick is %s.', self.nick)
|
||||||
for callback in self.callbacks:
|
self.queueMsg(ircmsgs.nick(self.nick))
|
||||||
callback.reset()
|
log.info('Sending USER command, ident is %s, user is %s.',
|
||||||
|
self.ident, self.user)
|
||||||
|
self.queueMsg(ircmsgs.user(self.ident, self.user))
|
||||||
|
|
||||||
|
def _getNextNick(self):
|
||||||
|
if self.alternateNicks:
|
||||||
|
return self.alternateNicks.pop(0)
|
||||||
|
else:
|
||||||
|
nick = conf.supybot.nick()
|
||||||
|
for c in '`_^':
|
||||||
|
if nick.endswith(c):
|
||||||
|
if len(nick) >= 9: # The max length on many servers.
|
||||||
|
nick = nick.rstrip(c)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return nick + c
|
||||||
|
else:
|
||||||
|
return nick + c
|
||||||
|
for c in '`_^':
|
||||||
|
if nick.startswith(c):
|
||||||
|
if len(nick) >= 9:
|
||||||
|
nick = nick.lstrip(c)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return c + nick
|
||||||
|
else:
|
||||||
|
return c + nick
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<irclib.Irc object for %s>' % self.server
|
return '<irclib.Irc object for %s>' % self.network
|
||||||
|
|
||||||
def addCallback(self, callback):
|
def addCallback(self, callback):
|
||||||
"""Adds a callback to the callbacks list."""
|
"""Adds a callback to the callbacks list."""
|
||||||
self.callbacks.append(callback)
|
self.callbacks.append(callback)
|
||||||
utils.sortBy(lambda cb: cb.priority, self.callbacks)
|
utils.sortBy(operator.attrgetter('priority'), self.callbacks)
|
||||||
|
|
||||||
def getCallback(self, name):
|
def getCallback(self, name):
|
||||||
"""Gets a given callback by name."""
|
"""Gets a given callback by name."""
|
||||||
@ -600,15 +623,16 @@ class Irc(IrcCommandDispatcher):
|
|||||||
def do376(self, msg):
|
def do376(self, msg):
|
||||||
log.info('Got end of MOTD from %s', self.server)
|
log.info('Got end of MOTD from %s', self.server)
|
||||||
self.afterConnect = True
|
self.afterConnect = True
|
||||||
|
# Let's reset nicks in case we had to use a weird one.
|
||||||
|
self.alternateNicks = conf.supybot.nick.alternates()[:]
|
||||||
do377 = do422 = do376
|
do377 = do422 = do376
|
||||||
|
|
||||||
def do433(self, msg):
|
def do433(self, msg):
|
||||||
"""Handles 'nickname already in use' messages."""
|
"""Handles 'nickname already in use' messages."""
|
||||||
if self.nick != self.originalNick or not self.afterConnect:
|
newNick = self._getNextNick()
|
||||||
newNick = self.nickmods.next() % self.originalNick
|
log.info('Got 433: %s is in use. Trying %s.', self.nick, newNick)
|
||||||
log.info('Got 433: %s is in use. Trying %s.', self.nick, newNick)
|
self.sendMsg(ircmsgs.nick(newNick))
|
||||||
self.sendMsg(ircmsgs.nick(newNick))
|
do432 = do433 # 432: Erroneous nickname.
|
||||||
do432 = do433
|
|
||||||
|
|
||||||
def doJoin(self, msg):
|
def doJoin(self, msg):
|
||||||
if msg.nick == self.nick:
|
if msg.nick == self.nick:
|
||||||
|
@ -52,6 +52,7 @@ supybot.log.detailedTracebacks: False
|
|||||||
supybot.throttleTime: 0
|
supybot.throttleTime: 0
|
||||||
supybot.prefixChars: @
|
supybot.prefixChars: @
|
||||||
supybot.protocols.irc.throttleTime: -1
|
supybot.protocols.irc.throttleTime: -1
|
||||||
|
supybot.networks.test.server: should.not.need.this
|
||||||
""")
|
""")
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ class IrcStateTestCase(SupyTestCase):
|
|||||||
|
|
||||||
class IrcTestCase(SupyTestCase):
|
class IrcTestCase(SupyTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.irc = irclib.Irc('nick')
|
self.irc = irclib.Irc('test')
|
||||||
_ = self.irc.takeMsg() # NICK
|
_ = self.irc.takeMsg() # NICK
|
||||||
_ = self.irc.takeMsg() # USER
|
_ = self.irc.takeMsg() # USER
|
||||||
|
|
||||||
@ -325,6 +325,8 @@ class IrcTestCase(SupyTestCase):
|
|||||||
self.failUnless(msg.command == 'NICK' and msg.args[0] != self.irc.nick)
|
self.failUnless(msg.command == 'NICK' and msg.args[0] != self.irc.nick)
|
||||||
|
|
||||||
def testSendBeforeQueue(self):
|
def testSendBeforeQueue(self):
|
||||||
|
while self.irc.takeMsg() is not None:
|
||||||
|
self.irc.takeMsg()
|
||||||
self.irc.queueMsg(ircmsgs.IrcMsg('NOTICE #foo bar'))
|
self.irc.queueMsg(ircmsgs.IrcMsg('NOTICE #foo bar'))
|
||||||
self.irc.sendMsg(ircmsgs.IrcMsg('PRIVMSG #foo yeah!'))
|
self.irc.sendMsg(ircmsgs.IrcMsg('PRIVMSG #foo yeah!'))
|
||||||
msg = self.irc.takeMsg()
|
msg = self.irc.takeMsg()
|
||||||
@ -392,23 +394,35 @@ class IrcCallbackTestCase(SupyTestCase):
|
|||||||
self.assertEqual(doCommandCatcher.L, commands)
|
self.assertEqual(doCommandCatcher.L, commands)
|
||||||
|
|
||||||
def testFirstCommands(self):
|
def testFirstCommands(self):
|
||||||
nick = 'nick'
|
try:
|
||||||
user = 'user any user'
|
originalNick = conf.supybot.nick()
|
||||||
password = 'password'
|
originalUser = conf.supybot.user()
|
||||||
expected = [ircmsgs.nick(nick), ircmsgs.user(nick, user)]
|
originalPassword = conf.supybot.networks.test.password()
|
||||||
irc = irclib.Irc(nick, user)
|
nick = 'nick'
|
||||||
msgs = [irc.takeMsg()]
|
conf.supybot.nick.setValue(nick)
|
||||||
while msgs[-1] != None:
|
user = 'user any user'
|
||||||
msgs.append(irc.takeMsg())
|
conf.supybot.user.setValue(user)
|
||||||
msgs.pop()
|
expected = [ircmsgs.nick(nick), ircmsgs.user('supybot', user)]
|
||||||
self.assertEqual(msgs, expected)
|
irc = irclib.Irc('test')
|
||||||
irc = irclib.Irc(nick, user, password=password)
|
msgs = [irc.takeMsg()]
|
||||||
msgs = [irc.takeMsg()]
|
while msgs[-1] != None:
|
||||||
while msgs[-1] != None:
|
msgs.append(irc.takeMsg())
|
||||||
msgs.append(irc.takeMsg())
|
msgs.pop()
|
||||||
msgs.pop()
|
self.assertEqual(msgs, expected)
|
||||||
expected.insert(0, ircmsgs.password(password))
|
password = 'password'
|
||||||
self.assertEqual(msgs, expected)
|
conf.supybot.networks.test.password.setValue(password)
|
||||||
|
irc = irclib.Irc('test')
|
||||||
|
msgs = [irc.takeMsg()]
|
||||||
|
while msgs[-1] != None:
|
||||||
|
msgs.append(irc.takeMsg())
|
||||||
|
msgs.pop()
|
||||||
|
expected.insert(0, ircmsgs.password(password))
|
||||||
|
self.assertEqual(msgs, expected)
|
||||||
|
finally:
|
||||||
|
conf.supybot.nick.setValue(nick)
|
||||||
|
conf.supybot.user.setValue(user)
|
||||||
|
conf.supybot.networks.test.password.setValue(password)
|
||||||
|
conf.supybot.nick.setValue(nick)
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user