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,50 +571,73 @@ 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:
if not isinstance(self.irc, irclib.Irc): try:
self.irc.reply(s, private=self.private, notice=self.notice, if not isinstance(self.irc, irclib.Irc):
to=self.to, noLengthCheck=self.noLengthCheck, self.irc.reply(s, to=self.to,
prefixName=self.prefixName, action=self.action) notice=self.notice,
elif self.noLengthCheck: action=self.action,
self.irc.queueMsg(reply(msg, s, prefixName=self.prefixName, private=self.private,
private=self.private, to=self.to, prefixName=self.prefixName,
action=self.action,notice=self.notice)) noLengthCheck=self.noLengthCheck)
else: elif self.noLengthCheck:
s = ircutils.safeArgument(s) # noLengthCheck only matters to IrcObjectProxy, so it's not
allowedLength = 450 - len(self.irc.prefix) # used here. Just in case you were wondering.
maximumLength = allowedLength*conf.supybot.reply.maximumMores() self.irc.queueMsg(reply(msg, s, to=self.to,
if len(s) > maximumLength: notice=self.notice,
log.warning('Truncating to %s bytes from %s bytes', action=self.action,
maximumLength, len(s)) private=self.private,
s = s[:maximumLength] prefixName=self.prefixName))
if len(s) < allowedLength or conf.supybot.reply.truncate(): else:
s = s[:allowedLength+20] # In case we're truncating. s = ircutils.safeArgument(s)
self.irc.queueMsg(reply(msg, s, self.prefixName, allowedLength = 450 - len(self.irc.prefix)
self.private,self.notice,self.to)) maximumMores = conf.supybot.reply.maximumMores()
self.finished = True maximumLength = allowedLength * maximumMores
return if len(s) > maximumLength:
msgs = textwrap.wrap(s, allowedLength-30) # -30 is for "nick:" log.warning('Truncating to %s bytes from %s bytes',
msgs.reverse() maximumLength, len(s))
response = msgs.pop() s = s[:maximumLength]
if msgs: if len(s) < allowedLength or conf.supybot.reply.truncate():
n = ircutils.bold('(%s)') # In case we're truncating, we add 20 to allowedLength,
n %= utils.nItems('message', len(msgs), 'more') # because our allowedLength is shortened for the
response = '%s %s' % (response, n) # "(XX more messages)" trailer.
prefix = msg.prefix s = s[:allowedLength+20]
if self.to and ircutils.isNick(self.to): # There's no need for action=self.action here because
try: # action implies noLengthCheck, which has already been
prefix=self.getRealIrc().state.nickToHostmask(self.to) # handled. Let's stick an assert in here just in case.
except KeyError: assert not self.action
pass # We'll leave it as it is. self.irc.queueMsg(reply(msg, s, to=self.to,
mask = prefix.split('!', 1)[1] notice=self.notice,
Privmsg._mores[mask] = msgs private=self.private,
private = self.private or not ircutils.isChannel(msg.args[0]) prefixName=self.prefixName))
Privmsg._mores[msg.nick] = (private, msgs) self.finished = True
self.irc.queueMsg(reply(msg, response, return
prefixName=self.prefixName, msgs = textwrap.wrap(s,allowedLength-30) # -30 is for nick:
private=self.private, to=self.to, msgs.reverse()
action=self.action,notice=self.notice)) response = msgs.pop()
self.finished = True if msgs:
n = ircutils.bold('(%s)')
n %= utils.nItems('message', len(msgs), 'more')
response = '%s %s' % (response, n)
prefix = msg.prefix
if self.to and ircutils.isNick(self.to):
try:
state = self.getRealIrc().state
prefix = state.nickToHostmask(self.to)
except KeyError:
pass # We'll leave it as it is.
mask = prefix.split('!', 1)[1]
Privmsg._mores[mask] = msgs
public = ircutils.isChannel(msg.args[0])
private = self.private or not public
Privmsg._mores[msg.nick] = (private, msgs)
self.irc.queueMsg(reply(msg, response, to=self.to,
action=self.action,
notice=self.notice,
private=self.private,
prefixName=self.prefixName))
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')