callbacks: Move reply chunking from NestedCommandsIrcProxy to ReplyIrcProxy.

So non-commands also benefit from the chunking/mores.

Closes GH-183.
This commit is contained in:
Valentin Lorentz 2020-05-22 08:17:27 +02:00
parent b07619e26f
commit 67612b5338
2 changed files with 66 additions and 47 deletions

View File

@ -137,6 +137,17 @@ class LaterTestCase(ChannelPluginTestCase):
m = self.getMsg(' ') m = self.getMsg(' ')
self.assertEqual(str(m).strip(), self.assertEqual(str(m).strip(),
'PRIVMSG #test :foo: Sent just now: <%s> stuff' % self.prefix) 'PRIVMSG #test :foo: Sent just now: <%s> stuff' % self.prefix)
def testLargeMessage(self):
self.assertNotError('later tell foo ' + ' stuff'*100)
self.assertRegexp('later notes', 'foo')
testPrefix = 'foo!bar@baz'
self.irc.feedMsg(ircmsgs.privmsg(self.channel, 'something',
prefix=testPrefix))
m = self.getMsg(' ')
self.assertEqual(str(m).strip(),
'PRIVMSG #test :foo: Sent just now: <test> '
+ 'stuff ' * 70 + ' \x02(1 more message)\x02')
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -281,10 +281,10 @@ def _prepareReply(irc, msg,
prefixLength = len(prefix) prefixLength = len(prefix)
return (replyMaker, target, to, overheadLength, prefixLength) return (replyMaker, target, to, private, overheadLength, prefixLength)
def _makeReply(irc, msg, s, **kwargs): def _makeReply(irc, msg, s, **kwargs):
(replyMaker, _, _, _, _) = _prepareReply(irc, msg, **kwargs) (replyMaker, _, _, _, _, _) = _prepareReply(irc, msg, **kwargs)
return replyMaker(s) return replyMaker(s)
@ -695,6 +695,8 @@ class ReplyIrcProxy(RichReplyMethods):
"""This class is a thin wrapper around an irclib.Irc object that gives it """This class is a thin wrapper around an irclib.Irc object that gives it
the reply() and error() methods (as well as everything in RichReplyMethods, the reply() and error() methods (as well as everything in RichReplyMethods,
based on those two).""" based on those two)."""
_mores = ircutils.IrcDict()
def __init__(self, irc, msg): def __init__(self, irc, msg):
self.irc = irc self.irc = irc
self.msg = msg self.msg = msg
@ -734,18 +736,63 @@ class ReplyIrcProxy(RichReplyMethods):
assert not isinstance(s, ircmsgs.IrcMsg), \ assert not isinstance(s, ircmsgs.IrcMsg), \
'Old code alert: there is no longer a "msg" argument to reply.' 'Old code alert: there is no longer a "msg" argument to reply.'
kwargs.pop('noLengthCheck', None) kwargs.pop('noLengthCheck', None)
m = _makeReply(self, msg, s, **kwargs) return self._replyFinal(msg, s, **kwargs)
self.irc.queueMsg(m)
return m
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.irc, attr) return getattr(self.irc, attr)
def _replyFinal(self, msg, s, sendImmediately=False, **kwargs):
if sendImmediately:
sendMsg = self.irc.sendMsg
else:
sendMsg = self.irc.queueMsg
(replyMaker, target, to, private, overheadLength, prefixLength) = \
_prepareReply(self, msg, **kwargs)
s = ircutils.safeArgument(s)
msgs = _splitReply(
s,
irc=self.irc,
target=target,
replyMaker=replyMaker,
overheadLength=overheadLength,
prefixLength=prefixLength,
)
instant = conf.get(conf.supybot.reply.mores.instant,
channel=target, network=self.irc.network)
while instant > 1 and msgs:
instant -= 1
response = msgs.pop()
sendMsg(response)
# XXX We should somehow allow these to be returned, but
# until someone complains, we'll be fine :) We
# can't return from here, though, for obvious
# reasons.
# return m
if not msgs:
return
response = msgs.pop()
prefix = msg.prefix
if to and ircutils.isNick(to):
try:
state = self.getRealIrc().state
prefix = state.nickToHostmask(to)
except KeyError:
pass # We'll leave it as it is.
mask = prefix.split('!', 1)[1]
self._mores[mask] = msgs
public = bool(self.msg.channel)
private = private or not public
self._mores[msg.nick] = (private, msgs)
sendMsg(response)
return response
SimpleProxy = ReplyIrcProxy # Backwards-compatibility SimpleProxy = ReplyIrcProxy # Backwards-compatibility
class NestedCommandsIrcProxy(ReplyIrcProxy): class NestedCommandsIrcProxy(ReplyIrcProxy):
"A proxy object to allow proper nesting of commands (even threaded ones)." "A proxy object to allow proper nesting of commands (even threaded ones)."
_mores = ircutils.IrcDict()
def __init__(self, irc, msg, args, nested=0): def __init__(self, irc, msg, args, nested=0):
assert isinstance(args, list), 'Args should be a list, not a string.' assert isinstance(args, list), 'Args should be a list, not a string.'
super(NestedCommandsIrcProxy, self).__init__(irc, msg) super(NestedCommandsIrcProxy, self).__init__(irc, msg)
@ -1028,47 +1075,8 @@ class NestedCommandsIrcProxy(ReplyIrcProxy):
sendMsg(m) sendMsg(m)
return m return m
else: else:
(replyMaker, target, to, overheadLength, prefixLength) = \ # Format and split the reply, add to self._mores
_prepareReply(self, msg, **replyArgs) self._replyFinal(msg, s, **replyArgs)
s = ircutils.safeArgument(s)
msgs = _splitReply(
s,
irc=self.irc,
target=target,
replyMaker=replyMaker,
overheadLength=overheadLength,
prefixLength=prefixLength,
)
instant = conf.get(conf.supybot.reply.mores.instant,
channel=target, network=self.irc.network)
while instant > 1 and msgs:
instant -= 1
response = msgs.pop()
sendMsg(response)
# XXX We should somehow allow these to be returned, but
# until someone complains, we'll be fine :) We
# can't return from here, though, for obvious
# reasons.
# return m
if not msgs:
return
response = msgs.pop()
prefix = msg.prefix
if to and ircutils.isNick(to):
try:
state = self.getRealIrc().state
prefix = state.nickToHostmask(to)
except KeyError:
pass # We'll leave it as it is.
mask = prefix.split('!', 1)[1]
self._mores[mask] = msgs
public = bool(self.msg.channel)
private = self.private or not public
self._mores[msg.nick] = (private, msgs)
sendMsg(response)
return response
finally: finally:
self._resetReplyAttributes() self._resetReplyAttributes()
else: else: