mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 20:59:27 +01:00
Use CAP LS.
This commit is contained in:
parent
f85395d8b1
commit
e2b3b917e5
@ -350,7 +350,8 @@ class IrcState(IrcCommandDispatcher):
|
|||||||
__firewalled__ = {'addMsg': None}
|
__firewalled__ = {'addMsg': None}
|
||||||
def __init__(self, history=None, supported=None,
|
def __init__(self, history=None, supported=None,
|
||||||
nicksToHostmasks=None, channels=None,
|
nicksToHostmasks=None, channels=None,
|
||||||
capabilities_ack=None, capabilities_nak=None):
|
capabilities_ack=None, capabilities_nak=None,
|
||||||
|
capabilities_ls=None):
|
||||||
if history is None:
|
if history is None:
|
||||||
history = RingBuffer(conf.supybot.protocols.irc.maxHistoryLength())
|
history = RingBuffer(conf.supybot.protocols.irc.maxHistoryLength())
|
||||||
if supported is None:
|
if supported is None:
|
||||||
@ -361,6 +362,7 @@ class IrcState(IrcCommandDispatcher):
|
|||||||
channels = ircutils.IrcDict()
|
channels = ircutils.IrcDict()
|
||||||
self.capabilities_ack = capabilities_ack or set()
|
self.capabilities_ack = capabilities_ack or set()
|
||||||
self.capabilities_nak = capabilities_nak or set()
|
self.capabilities_nak = capabilities_nak or set()
|
||||||
|
self.capabilities_ls = capabilities_ls or {}
|
||||||
self.ircd = None
|
self.ircd = None
|
||||||
self.supported = supported
|
self.supported = supported
|
||||||
self.history = history
|
self.history = history
|
||||||
@ -949,6 +951,9 @@ class Irc(IrcCommandDispatcher):
|
|||||||
self.outstandingPing = False
|
self.outstandingPing = False
|
||||||
|
|
||||||
|
|
||||||
|
REQUEST_CAPABILITIES = {'account-notify', 'extended-join', 'multi-prefix',
|
||||||
|
'metadata-notify', 'account-tag'}
|
||||||
|
|
||||||
def _queueConnectMessages(self):
|
def _queueConnectMessages(self):
|
||||||
if self.zombie:
|
if self.zombie:
|
||||||
self.driver.die()
|
self.driver.die()
|
||||||
@ -987,14 +992,7 @@ class Irc(IrcCommandDispatcher):
|
|||||||
# in telling between ACK and NAK
|
# in telling between ACK and NAK
|
||||||
# * using sendMsg instead of queueMsg because these messages cannot
|
# * using sendMsg instead of queueMsg because these messages cannot
|
||||||
# be throttled.
|
# be throttled.
|
||||||
for cap in ('account-notify', 'extended-join', 'multi-prefix',
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('LS', '302')))
|
||||||
'metadata-notify', 'account-tag'):
|
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', cap)))
|
|
||||||
|
|
||||||
if self.sasl:
|
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', 'sasl')))
|
|
||||||
else:
|
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
|
||||||
|
|
||||||
def doAuthenticate(self, msg):
|
def doAuthenticate(self, msg):
|
||||||
if len(msg.args) == 1 and msg.args[0] == '+':
|
if len(msg.args) == 1 and msg.args[0] == '+':
|
||||||
@ -1026,27 +1024,69 @@ class Irc(IrcCommandDispatcher):
|
|||||||
self.sendMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', args=(authstring,)))
|
self.sendMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', args=(authstring,)))
|
||||||
|
|
||||||
def doCap(self, msg):
|
def doCap(self, msg):
|
||||||
|
if msg.args[1] == 'ACK':
|
||||||
|
self.doCapAck(msg)
|
||||||
|
elif msg.args[1] == 'NAK':
|
||||||
|
self.doCapNak(msg)
|
||||||
|
elif msg.args[1] == 'LS':
|
||||||
|
self.doCapLs(msg)
|
||||||
|
def doCapAck(self, msg):
|
||||||
if len(msg.args) != 3:
|
if len(msg.args) != 3:
|
||||||
|
log.warning('Bad CAP ACK from server: %r', msg)
|
||||||
return
|
return
|
||||||
for cap in msg.args[2].split(' '):
|
for cap in msg.args[2].split(' '):
|
||||||
if msg.args[1] == 'ACK':
|
log.info('%s: Server acknowledged capability %r',
|
||||||
log.info('%s: Server acknowledged capability %r',
|
self.network, cap)
|
||||||
self.network, cap)
|
self.state.capabilities_ack.add(cap)
|
||||||
self.state.capabilities_ack.add(cap)
|
|
||||||
|
|
||||||
if cap == 'sasl':
|
if cap == 'sasl':
|
||||||
self.sendMsg(ircmsgs.IrcMsg(
|
self.sendMsg(ircmsgs.IrcMsg(
|
||||||
command='AUTHENTICATE',
|
command='AUTHENTICATE',
|
||||||
args=(self.sasl.upper(),)))
|
args=(self.sasl.upper(),)))
|
||||||
elif msg.args[1] == 'NAK':
|
def doCapNak(self, msg):
|
||||||
self.state.capabilities_nak.add(cap)
|
if len(msg.args) != 3:
|
||||||
log.warning('%s: Server refused capability %r',
|
log.warning('Bad CAP NAK from server: %r', msg)
|
||||||
self.network, cap)
|
return
|
||||||
|
for cap in msg.args[2].split(' '):
|
||||||
|
self.state.capabilities_nak.add(cap)
|
||||||
|
log.warning('%s: Server refused capability %r',
|
||||||
|
self.network, cap)
|
||||||
|
|
||||||
if cap == 'sasl':
|
if cap == 'sasl':
|
||||||
self.sendMsg(ircmsgs.IrcMsg(
|
self.sendMsg(ircmsgs.IrcMsg(
|
||||||
command='CAP',
|
command='CAP',
|
||||||
args=('END',)))
|
args=('END',)))
|
||||||
|
def _addCapabilities(self, capstring):
|
||||||
|
for item in capstring.split():
|
||||||
|
while item.startswith(('=', '~')):
|
||||||
|
item = item[1:]
|
||||||
|
if '=' in item:
|
||||||
|
(cap, value) = item.split('=', 1)
|
||||||
|
self.state.capabilities_ls[cap] = value
|
||||||
|
else:
|
||||||
|
self.state.capabilities_ls[item] = None
|
||||||
|
def doCapLs(self, msg):
|
||||||
|
if len(msg.args) == 4:
|
||||||
|
# Multi-line LS
|
||||||
|
if msg.args[2] != '*':
|
||||||
|
log.warning('Bad CAP LS from server: %r', msg)
|
||||||
|
return
|
||||||
|
self._addCapabilities(msg.args[3])
|
||||||
|
elif len(msg.args) == 3: # End of LS
|
||||||
|
self._addCapabilities(msg.args[2])
|
||||||
|
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
||||||
|
self.REQUEST_CAPABILITIES
|
||||||
|
for cap in common_supported_capabilities:
|
||||||
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', cap)))
|
||||||
|
|
||||||
|
if 'sasl' in self.state.capabilities_ls and self.sasl:
|
||||||
|
# TODO: use the value of self.state.capabilities_ls['sasl']
|
||||||
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', 'sasl')))
|
||||||
|
else:
|
||||||
|
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
||||||
|
else:
|
||||||
|
log.warning('Bad CAP LS from server: %r', msg)
|
||||||
|
return
|
||||||
|
|
||||||
def monitor(self, targets):
|
def monitor(self, targets):
|
||||||
"""Increment a counter of how many callbacks monitor each target;
|
"""Increment a counter of how many callbacks monitor each target;
|
||||||
|
@ -386,16 +386,26 @@ class IrcTestCase(SupyTestCase):
|
|||||||
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
|
self.failUnless(m.args == ('LS', '302'), 'Expected CAP LS 302, got %r.' % m)
|
||||||
|
# TODO
|
||||||
|
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||||
|
args=('*', 'LS', '*', 'account-tag multi-prefix')))
|
||||||
|
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||||
|
args=('*', 'LS', 'extended-join')))
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
|
self.assertEqual(m.args, ('REQ', 'account-tag'), m)
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
|
self.assertEqual(m.args, ('REQ', 'multi-prefix'), m)
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
|
self.assertEqual(m.args, ('REQ', 'extended-join'), m)
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
|
self.assertEqual(m.args, ('END',), m)
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m is None, m)
|
||||||
|
|
||||||
def testPingResponse(self):
|
def testPingResponse(self):
|
||||||
self.irc.feedMsg(ircmsgs.ping('123'))
|
self.irc.feedMsg(ircmsgs.ping('123'))
|
||||||
@ -493,16 +503,11 @@ class IrcCallbackTestCase(SupyTestCase):
|
|||||||
expected = [
|
expected = [
|
||||||
ircmsgs.nick(nick),
|
ircmsgs.nick(nick),
|
||||||
ircmsgs.user('limnoria', user),
|
ircmsgs.user('limnoria', user),
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('REQ', 'account-notify')),
|
ircmsgs.IrcMsg(command='CAP', args=('LS', '302')),
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('REQ', 'extended-join')),
|
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('REQ', 'multi-prefix')),
|
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('REQ', 'metadata-notify')),
|
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('REQ', 'account-tag')),
|
|
||||||
ircmsgs.IrcMsg(command='CAP', args=('END',)),
|
|
||||||
]
|
]
|
||||||
irc = irclib.Irc('test')
|
irc = irclib.Irc('test')
|
||||||
msgs = [irc.takeMsg()]
|
msgs = [irc.takeMsg()]
|
||||||
while msgs[-1] != None:
|
while msgs[-1] is not None:
|
||||||
msgs.append(irc.takeMsg())
|
msgs.append(irc.takeMsg())
|
||||||
msgs.pop()
|
msgs.pop()
|
||||||
self.assertEqual(msgs, expected)
|
self.assertEqual(msgs, expected)
|
||||||
@ -510,7 +515,7 @@ class IrcCallbackTestCase(SupyTestCase):
|
|||||||
conf.supybot.networks.test.password.setValue(password)
|
conf.supybot.networks.test.password.setValue(password)
|
||||||
irc = irclib.Irc('test')
|
irc = irclib.Irc('test')
|
||||||
msgs = [irc.takeMsg()]
|
msgs = [irc.takeMsg()]
|
||||||
while msgs[-1] != None:
|
while msgs[-1] is not None:
|
||||||
msgs.append(irc.takeMsg())
|
msgs.append(irc.takeMsg())
|
||||||
msgs.pop()
|
msgs.pop()
|
||||||
expected.insert(0, ircmsgs.password(password))
|
expected.insert(0, ircmsgs.password(password))
|
||||||
|
Loading…
Reference in New Issue
Block a user