mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-19 08:59:27 +01: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()
|
||||
network = conf.supybot.networks.get(defaultNetwork)
|
||||
server = network.server()
|
||||
password = network.password()
|
||||
if ':' in server:
|
||||
serverAndPort = server.split(':', 1)
|
||||
serverAndPort[1] = int(serverAndPort[1])
|
||||
@ -251,8 +250,7 @@ if __name__ == '__main__':
|
||||
import supybot.callbacks as callbacks
|
||||
import supybot.Owner as Owner
|
||||
|
||||
irc = irclib.Irc(nick, user=user, ident=ident,
|
||||
network=defaultNetwork, password=password)
|
||||
irc = irclib.Irc(network=defaultNetwork)
|
||||
callback = Owner.Class()
|
||||
irc.addCallback(callback)
|
||||
driver = drivers.newDriver(server, irc)
|
||||
|
17
src/conf.py
17
src/conf.py
@ -129,6 +129,9 @@ class ValidNick(registry.String):
|
||||
else:
|
||||
registry.String.setValue(self, v)
|
||||
|
||||
class ValidNicks(registry.SpaceSeparatedListOf):
|
||||
Value = ValidNick
|
||||
|
||||
class ValidChannel(registry.String):
|
||||
"""Value must be a valid IRC channel name."""
|
||||
def setValue(self, v):
|
||||
@ -142,7 +145,12 @@ class ValidChannel(registry.String):
|
||||
registry.String.setValue(self, v)
|
||||
|
||||
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',
|
||||
ValidNick('supybot', """Determines the bot's ident string, if the server
|
||||
@ -450,13 +458,6 @@ registerChannelValue(supybot.replies, 'possibleBug',
|
||||
# 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',
|
||||
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
|
||||
|
100
src/irclib.py
100
src/irclib.py
@ -36,6 +36,7 @@ import supybot.fix as fix
|
||||
import copy
|
||||
import sets
|
||||
import time
|
||||
import operator
|
||||
from itertools import imap, chain, cycle
|
||||
|
||||
import supybot.log as log
|
||||
@ -332,7 +333,8 @@ class IrcState(IrcCommandDispatcher):
|
||||
chan = ChannelState()
|
||||
chan.addUser(msg.nick)
|
||||
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):
|
||||
channel = msg.args[0]
|
||||
@ -441,65 +443,86 @@ class Irc(IrcCommandDispatcher):
|
||||
_nickSetters = sets.Set(['001', '002', '003', '004', '250', '251', '252',
|
||||
'254', '255', '265', '266', '372', '375', '376',
|
||||
'333', '353', '332', '366', '005'])
|
||||
def __init__(self, nick, user='', ident='',
|
||||
network='unset', password='', callbacks=None):
|
||||
def __init__(self, network, callbacks=None):
|
||||
world.ircs.append(self)
|
||||
self.originalNick = intern(nick)
|
||||
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')
|
||||
self.network = network
|
||||
if callbacks is None:
|
||||
self.callbacks = []
|
||||
else:
|
||||
self.callbacks = callbacks
|
||||
self.state = IrcState()
|
||||
self.queue = IrcMsgQueue()
|
||||
self.lastTake = 0
|
||||
self.server = 'unset'
|
||||
self.afterConnect = False
|
||||
self.fastqueue = smallqueue()
|
||||
self.lastping = time.time()
|
||||
self.outstandingPing = False
|
||||
self.driver = None # The driver should set this later.
|
||||
if self.password:
|
||||
self.queue.enqueue(ircmsgs.password(self.password))
|
||||
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))
|
||||
self._setNonResettingVariables()
|
||||
self._queueConnectMessages()
|
||||
|
||||
def reset(self):
|
||||
"""Resets the Irc object. Called when the driver reconnects."""
|
||||
self.nick = self.originalNick
|
||||
self.network = self.originalNetwork
|
||||
self.prefix = '%s!%s@%s' % (self.nick, self.ident, 'unset.domain')
|
||||
self._setNonResettingVariables()
|
||||
self._queueConnectMessages()
|
||||
self.state.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.afterConnect = False
|
||||
self.lastping = time.time()
|
||||
self.outstandingPing = False
|
||||
self.fastqueue = queue()
|
||||
|
||||
def _queueConnectMessages(self):
|
||||
if self.password:
|
||||
self.queue.enqueue(ircmsgs.password(self.password))
|
||||
self.queue.enqueue(ircmsgs.nick(self.nick))
|
||||
self.queue.enqueue(ircmsgs.user(self.ident, self.user))
|
||||
for callback in self.callbacks:
|
||||
callback.reset()
|
||||
log.info('Sending PASS command, not logging the password.')
|
||||
self.queueMsg(ircmsgs.password(self.password))
|
||||
log.info('Sending NICK command, nick is %s.', self.nick)
|
||||
self.queueMsg(ircmsgs.nick(self.nick))
|
||||
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):
|
||||
return '<irclib.Irc object for %s>' % self.server
|
||||
return '<irclib.Irc object for %s>' % self.network
|
||||
|
||||
def addCallback(self, callback):
|
||||
"""Adds a callback to the callbacks list."""
|
||||
self.callbacks.append(callback)
|
||||
utils.sortBy(lambda cb: cb.priority, self.callbacks)
|
||||
utils.sortBy(operator.attrgetter('priority'), self.callbacks)
|
||||
|
||||
def getCallback(self, name):
|
||||
"""Gets a given callback by name."""
|
||||
@ -600,15 +623,16 @@ class Irc(IrcCommandDispatcher):
|
||||
def do376(self, msg):
|
||||
log.info('Got end of MOTD from %s', self.server)
|
||||
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
|
||||
|
||||
def do433(self, msg):
|
||||
"""Handles 'nickname already in use' messages."""
|
||||
if self.nick != self.originalNick or not self.afterConnect:
|
||||
newNick = self.nickmods.next() % self.originalNick
|
||||
newNick = self._getNextNick()
|
||||
log.info('Got 433: %s is in use. Trying %s.', self.nick, newNick)
|
||||
self.sendMsg(ircmsgs.nick(newNick))
|
||||
do432 = do433
|
||||
do432 = do433 # 432: Erroneous nickname.
|
||||
|
||||
def doJoin(self, msg):
|
||||
if msg.nick == self.nick:
|
||||
|
@ -52,6 +52,7 @@ supybot.log.detailedTracebacks: False
|
||||
supybot.throttleTime: 0
|
||||
supybot.prefixChars: @
|
||||
supybot.protocols.irc.throttleTime: -1
|
||||
supybot.networks.test.server: should.not.need.this
|
||||
""")
|
||||
fd.close()
|
||||
|
||||
|
@ -304,7 +304,7 @@ class IrcStateTestCase(SupyTestCase):
|
||||
|
||||
class IrcTestCase(SupyTestCase):
|
||||
def setUp(self):
|
||||
self.irc = irclib.Irc('nick')
|
||||
self.irc = irclib.Irc('test')
|
||||
_ = self.irc.takeMsg() # NICK
|
||||
_ = self.irc.takeMsg() # USER
|
||||
|
||||
@ -325,6 +325,8 @@ class IrcTestCase(SupyTestCase):
|
||||
self.failUnless(msg.command == 'NICK' and msg.args[0] != self.irc.nick)
|
||||
|
||||
def testSendBeforeQueue(self):
|
||||
while self.irc.takeMsg() is not None:
|
||||
self.irc.takeMsg()
|
||||
self.irc.queueMsg(ircmsgs.IrcMsg('NOTICE #foo bar'))
|
||||
self.irc.sendMsg(ircmsgs.IrcMsg('PRIVMSG #foo yeah!'))
|
||||
msg = self.irc.takeMsg()
|
||||
@ -392,23 +394,35 @@ class IrcCallbackTestCase(SupyTestCase):
|
||||
self.assertEqual(doCommandCatcher.L, commands)
|
||||
|
||||
def testFirstCommands(self):
|
||||
try:
|
||||
originalNick = conf.supybot.nick()
|
||||
originalUser = conf.supybot.user()
|
||||
originalPassword = conf.supybot.networks.test.password()
|
||||
nick = 'nick'
|
||||
conf.supybot.nick.setValue(nick)
|
||||
user = 'user any user'
|
||||
password = 'password'
|
||||
expected = [ircmsgs.nick(nick), ircmsgs.user(nick, user)]
|
||||
irc = irclib.Irc(nick, user)
|
||||
conf.supybot.user.setValue(user)
|
||||
expected = [ircmsgs.nick(nick), ircmsgs.user('supybot', user)]
|
||||
irc = irclib.Irc('test')
|
||||
msgs = [irc.takeMsg()]
|
||||
while msgs[-1] != None:
|
||||
msgs.append(irc.takeMsg())
|
||||
msgs.pop()
|
||||
self.assertEqual(msgs, expected)
|
||||
irc = irclib.Irc(nick, user, password=password)
|
||||
password = 'password'
|
||||
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:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user