mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-23 10:34:19 +01:00
NickCapture & core: Add support for MONITOR. Closes GH-842.
This commit is contained in:
parent
ba495f5719
commit
59d542bb70
@ -45,6 +45,12 @@ class NickCapture(callbacks.Plugin):
|
||||
self.__parent = super(NickCapture, self)
|
||||
self.__parent.__init__(irc)
|
||||
self.lastIson = 0
|
||||
self.monitoring = []
|
||||
|
||||
def die(self):
|
||||
for irc in self.monitoring:
|
||||
nick = self._getNick(irc.network)
|
||||
irc.unmonitor(nick)
|
||||
|
||||
def _getNick(self, network):
|
||||
network_nick = conf.supybot.networks.get(network).nick()
|
||||
@ -60,10 +66,16 @@ class NickCapture(callbacks.Plugin):
|
||||
# We used to check this, but nicksToHostmasks is never cleared
|
||||
# except on reconnects, which can cause trouble.
|
||||
# if nick not in irc.state.nicksToHostmasks:
|
||||
self._ison(irc, nick)
|
||||
if 'monitor' in irc.state.supported:
|
||||
if irc not in self.monitoring:
|
||||
irc.monitor(nick)
|
||||
self.monitoring.append(irc)
|
||||
else:
|
||||
self._ison(irc, nick)
|
||||
self.__parent.__call__(irc, msg)
|
||||
|
||||
def _ison(self, irc, nick):
|
||||
assert 'monitor' not in irc.state.supported
|
||||
if self.registryValue('ison'):
|
||||
now = time.time()
|
||||
if now - self.lastIson > self.registryValue('ison.period'):
|
||||
@ -95,6 +107,16 @@ class NickCapture(callbacks.Plugin):
|
||||
nick = self._getNick(irc.network)
|
||||
if nick:
|
||||
self._sendNick(irc, nick)
|
||||
|
||||
def do731(self, irc, msg):
|
||||
"""This is sent by the MONITOR when a nick goes offline."""
|
||||
nick = self._getNick(irc.network)
|
||||
for target in msg.args[1].split(','):
|
||||
if nick == target:
|
||||
self._sendNick(irc, nick)
|
||||
self.monitoring.remove(irc)
|
||||
irc.unmonitor(nick)
|
||||
break
|
||||
NickCapture = internationalizeDocstring(NickCapture)
|
||||
|
||||
Class = NickCapture
|
||||
|
@ -666,6 +666,7 @@ class Irc(IrcCommandDispatcher):
|
||||
self._setNonResettingVariables()
|
||||
self._queueConnectMessages()
|
||||
self.startedSync = ircutils.IrcDict()
|
||||
self.monitoring = ircutils.IrcDict()
|
||||
|
||||
def isChannel(self, s):
|
||||
"""Helper function to check whether a given string is a channel on
|
||||
@ -1041,6 +1042,38 @@ class Irc(IrcCommandDispatcher):
|
||||
command='CAP',
|
||||
args=('END',)))
|
||||
|
||||
def monitor(self, targets):
|
||||
"""Increment a counter of how many callbacks monitor each target;
|
||||
and send a MONITOR + to the server if the target is not yet
|
||||
monitored."""
|
||||
if isinstance(targets, str):
|
||||
targets = [targets]
|
||||
not_yet_monitored = set()
|
||||
for target in targets:
|
||||
if target in self.monitoring:
|
||||
self.monitoring[target] += 1
|
||||
else:
|
||||
not_yet_monitored.add(target)
|
||||
self.monitoring[target] = 1
|
||||
if not_yet_monitored:
|
||||
self.queueMsg(ircmsgs.monitor('+', not_yet_monitored))
|
||||
return not_yet_monitored
|
||||
|
||||
def unmonitor(self, targets):
|
||||
"""Decrements a counter of how many callbacks monitor each target;
|
||||
and send a MONITOR - to the server if the counter drops to 0."""
|
||||
if isinstance(targets, str):
|
||||
targets = [targets]
|
||||
should_be_unmonitored = set()
|
||||
for target in targets:
|
||||
self.monitoring[target] -= 1
|
||||
if self.monitoring[target] == 0:
|
||||
del self.monitoring[target]
|
||||
should_be_unmonitored.add(target)
|
||||
if should_be_unmonitored:
|
||||
self.queueMsg(ircmsgs.monitor('-', should_be_unmonitored))
|
||||
return should_be_unmonitored
|
||||
|
||||
def do903(self, msg):
|
||||
log.info('%s: SASL authentication successful', self.network)
|
||||
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
||||
|
@ -855,6 +855,19 @@ def ison(nick, prefix='', msg=None):
|
||||
prefix = msg.prefix
|
||||
return IrcMsg(prefix=prefix, command='ISON', args=(nick,), msg=msg)
|
||||
|
||||
def monitor(subcommand, nicks=None, prefix='', msg=None):
|
||||
if conf.supybot.protocols.irc.strictRfc():
|
||||
assert isNick(nick), repr(nick)
|
||||
assert subcommand in '+-CLS'
|
||||
if subcommand in 'CLS':
|
||||
assert nicks is None
|
||||
if msg and not prefix:
|
||||
prefix = msg.prefix
|
||||
if not isinstance(nicks, str):
|
||||
nicks = ','.join(nicks)
|
||||
return IrcMsg(prefix=prefix, command='MONITOR', args=(subcommand, nicks),
|
||||
msg=msg)
|
||||
|
||||
def error(s, msg=None):
|
||||
return IrcMsg(command='ERROR', args=(s,), msg=msg)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user