Check that an action doesn't continue past the first reply.

This commit is contained in:
Jeremy Fincher 2004-04-17 14:07:55 +00:00
parent f150db596f
commit e194e89c85
2 changed files with 90 additions and 54 deletions

View File

@ -341,7 +341,6 @@ def checkCommandCapability(msg, cb, command):
return s return s
class RichReplyMethods(object): class RichReplyMethods(object):
"""This is a mixin so these replies need only be defined once. It operates """This is a mixin so these replies need only be defined once. It operates
under several assumptions, including the fact that "self" is an Irc object under several assumptions, including the fact that "self" is an Irc object
@ -363,8 +362,8 @@ class RichReplyMethods(object):
s = self.__makeReply(v, s) s = self.__makeReply(v, s)
self.reply(s, **kwargs) self.reply(s, **kwargs)
def replies(self, L, prefixer=''.join, def replies(self, L, prefixer=None, joiner=None,
joiner=utils.commaAndify, onlyPrefixFirst=False, **kwargs): onlyPrefixFirst=False, **kwargs):
if prefixer is None: if prefixer is None:
prefixer = '' prefixer = ''
if joiner is None: if joiner is None:
@ -432,13 +431,8 @@ class IrcObjectProxy(RichReplyMethods):
# tokenized commands. # tokenized commands.
self.args = copy.deepcopy(args) self.args = copy.deepcopy(args)
self.counter = 0 self.counter = 0
self.to = None self.finished = False # Used in _callInvalidCommands.
self.action = False self._resetReplyAttributes()
self.notice = False
self.private = False
self.finished = False
self.prefixName = conf.supybot.reply.withNickPrefix()
self.noLengthCheck = False
if not args: if not args:
self.finalEvaled = True self.finalEvaled = True
self._callInvalidCommands() self._callInvalidCommands()
@ -447,6 +441,14 @@ class IrcObjectProxy(RichReplyMethods):
world.commandsProcessed += 1 world.commandsProcessed += 1
self.evalArgs() self.evalArgs()
def _resetReplyAttributes(self):
self.to = None
self.action = False
self.notice = False
self.private = False
self.noLengthCheck = False
self.prefixName = conf.supybot.reply.withNickPrefix()
def evalArgs(self): def evalArgs(self):
while self.counter < len(self.args): while self.counter < len(self.args):
if type(self.args[self.counter]) == str: if type(self.args[self.counter]) == str:
@ -569,29 +571,47 @@ class IrcObjectProxy(RichReplyMethods):
self.prefixName = prefixName and self.prefixName and not self.action self.prefixName = prefixName and self.prefixName and not self.action
self.noLengthCheck=noLengthCheck or self.noLengthCheck or self.action self.noLengthCheck=noLengthCheck or self.noLengthCheck or self.action
if self.finalEvaled: if self.finalEvaled:
try:
if not isinstance(self.irc, irclib.Irc): if not isinstance(self.irc, irclib.Irc):
self.irc.reply(s, private=self.private, notice=self.notice, self.irc.reply(s, to=self.to,
to=self.to, noLengthCheck=self.noLengthCheck, notice=self.notice,
prefixName=self.prefixName, action=self.action) action=self.action,
private=self.private,
prefixName=self.prefixName,
noLengthCheck=self.noLengthCheck)
elif self.noLengthCheck: elif self.noLengthCheck:
self.irc.queueMsg(reply(msg, s, prefixName=self.prefixName, # noLengthCheck only matters to IrcObjectProxy, so it's not
private=self.private, to=self.to, # used here. Just in case you were wondering.
action=self.action,notice=self.notice)) self.irc.queueMsg(reply(msg, s, to=self.to,
notice=self.notice,
action=self.action,
private=self.private,
prefixName=self.prefixName))
else: else:
s = ircutils.safeArgument(s) s = ircutils.safeArgument(s)
allowedLength = 450 - len(self.irc.prefix) allowedLength = 450 - len(self.irc.prefix)
maximumLength = allowedLength*conf.supybot.reply.maximumMores() maximumMores = conf.supybot.reply.maximumMores()
maximumLength = allowedLength * maximumMores
if len(s) > maximumLength: if len(s) > maximumLength:
log.warning('Truncating to %s bytes from %s bytes', log.warning('Truncating to %s bytes from %s bytes',
maximumLength, len(s)) maximumLength, len(s))
s = s[:maximumLength] s = s[:maximumLength]
if len(s) < allowedLength or conf.supybot.reply.truncate(): if len(s) < allowedLength or conf.supybot.reply.truncate():
s = s[:allowedLength+20] # In case we're truncating. # In case we're truncating, we add 20 to allowedLength,
self.irc.queueMsg(reply(msg, s, self.prefixName, # because our allowedLength is shortened for the
self.private,self.notice,self.to)) # "(XX more messages)" trailer.
s = s[:allowedLength+20]
# There's no need for action=self.action here because
# action implies noLengthCheck, which has already been
# handled. Let's stick an assert in here just in case.
assert not self.action
self.irc.queueMsg(reply(msg, s, to=self.to,
notice=self.notice,
private=self.private,
prefixName=self.prefixName))
self.finished = True self.finished = True
return return
msgs = textwrap.wrap(s, allowedLength-30) # -30 is for "nick:" msgs = textwrap.wrap(s,allowedLength-30) # -30 is for nick:
msgs.reverse() msgs.reverse()
response = msgs.pop() response = msgs.pop()
if msgs: if msgs:
@ -601,18 +621,23 @@ class IrcObjectProxy(RichReplyMethods):
prefix = msg.prefix prefix = msg.prefix
if self.to and ircutils.isNick(self.to): if self.to and ircutils.isNick(self.to):
try: try:
prefix=self.getRealIrc().state.nickToHostmask(self.to) state = self.getRealIrc().state
prefix = state.nickToHostmask(self.to)
except KeyError: except KeyError:
pass # We'll leave it as it is. pass # We'll leave it as it is.
mask = prefix.split('!', 1)[1] mask = prefix.split('!', 1)[1]
Privmsg._mores[mask] = msgs Privmsg._mores[mask] = msgs
private = self.private or not ircutils.isChannel(msg.args[0]) public = ircutils.isChannel(msg.args[0])
private = self.private or not public
Privmsg._mores[msg.nick] = (private, msgs) Privmsg._mores[msg.nick] = (private, msgs)
self.irc.queueMsg(reply(msg, response, self.irc.queueMsg(reply(msg, response, to=self.to,
prefixName=self.prefixName, action=self.action,
private=self.private, to=self.to, notice=self.notice,
action=self.action,notice=self.notice)) private=self.private,
prefixName=self.prefixName))
self.finished = True self.finished = True
finally:
self._resetReplyAttributes()
else: else:
self.args[self.counter] = s self.args[self.counter] = s
self.evalArgs() self.evalArgs()

View File

@ -346,6 +346,17 @@ class PrivmsgTestCase(ChannelPluginTestCase):
self.assertRegexp('help first firstcmd', 'First', 0) # no re.I flag. self.assertRegexp('help first firstcmd', 'First', 0) # no re.I flag.
self.assertRegexp('help firstrepeat firstcmd', 'FirstRepeat', 0) self.assertRegexp('help firstrepeat firstcmd', 'FirstRepeat', 0)
class TwoRepliesFirstAction(callbacks.Privmsg):
def testactionreply(self, irc, msg, args):
irc.reply('foo', action=True)
irc.reply('bar') # We're going to check that this isn't an action.
def testNotActionSecondReply(self):
self.irc.addCallback(self.TwoRepliesFirstAction())
self.assertAction('testactionreply', 'foo')
m = self.getMsg(' ')
self.failIf(m.args[1].startswith('\x01ACTION'))
def testEmptyNest(self): def testEmptyNest(self):
try: try:
conf.supybot.reply.whenNotCommand.set('True') conf.supybot.reply.whenNotCommand.set('True')