Fixed several bugs and added the replies rich reply method.

This commit is contained in:
Jeremy Fincher 2004-01-19 20:51:04 +00:00
parent fca57c95de
commit 224cacc966
6 changed files with 109 additions and 65 deletions

View File

@ -182,12 +182,13 @@ class Factoids(plugins.ChannelDBHandler,
for result in cursor.fetchall():
factoids.append('(#%s) %s' % (counter, result[0]))
counter += 1
irc.reply('%r could be %s' % (key, ', or '.join(factoids)))
irc.replies(factoids, prefixer='%r could be ' % key,
joiner=', or ', onlyPrefixFirst=True)
else:
try:
irc.reply(cursor.fetchall()[number-1][0])
except IndexError:
irc.error('That\'s not a valid number for this key.')
irc.error('That\'s not a valid number for that key.')
return
def lock(self, irc, msg, args):

View File

@ -101,6 +101,7 @@ class RSS(callbacks.Privmsg, configurable.Mixin):
def __call__(self, irc, msg):
callbacks.Privmsg.__call__(self, irc, msg)
irc = callbacks.IrcObjectProxyRegexp(irc, msg)
feeds = self.configurables.getChannels('announce-news-feeds')
for (channel, d) in feeds.iteritems():
sep = self.configurables.get('headline-separator', channel)
@ -127,9 +128,7 @@ class RSS(callbacks.Privmsg, configurable.Mixin):
pre = prefix + name
if bold:
pre = ircutils.bold(pre)
headlines = sep.join(newheadlines)
s = '%s: %s' % (pre, headlines)
irc.queueMsg(ircmsgs.privmsg(channel, s))
irc.replies(headlines, prefixer=pre, joiner=sep)
def getFeed(self, url):
now = time.time()

View File

@ -296,38 +296,65 @@ class RichReplyMethods(object):
return s
def replySuccess(self, s='', **kwargs):
self.reply(self.__makeReply(conf.supybot.replies.success(), s),
**kwargs)
v = conf.supybot.replies.success.get(self.msg.args[0])
s = self.__makeReply(v(), s)
self.reply(s, **kwargs)
def replyError(self, s='', **kwargs):
self.reply(self.__makeReply(conf.supybot.replies.error(), s),
**kwargs)
v = conf.supybot.replies.error.get(self.msg.args[0])
s = self.__makeReply(v(), s)
self.reply(s, **kwargs)
def replies(self, L, prefixer=''.join,
joiner=utils.commaAndify, onlyPrefixFirst=False):
if prefixer is None:
prefixer = ''
if joiner is None:
joiner = utils.commaAndify
if isinstance(prefixer, basestring):
prefixer = prefixer.__add__
if isinstance(joiner, basestring):
joiner = joiner.join
if conf.supybot.reply.oneToOne():
self.reply(prefixer(joiner(L)))
else:
first = True
for s in L:
if onlyPrefixFirst:
if first:
self.reply(prefixer(s))
first = False
else:
self.reply(s)
else:
self.reply(prefixer(s))
def errorNoCapability(self, capability, s='', **kwargs):
log.warning('Denying %s for lacking %r capability',
self.msg.prefix, capability)
noCapability = conf.supybot.replies.noCapability()
s = self.__makeReply(noCapability % capability, s)
v = conf.supybot.replies.noCapability.get(self.msg.args[0])
s = self.__makeReply(v() % capability, s)
self.error(s, **kwargs)
def errorPossibleBug(self, s='', **kwargs):
v = conf.supybot.replies.possibleBug.get(self.msg.args[0])
if s:
s += ' (%s)' % conf.supybot.replies.possibleBug()
s += ' (%s)' % v()
else:
s = conf.supybot.replies.possibleBug()
s = v()
self.error(s, **kwargs)
def errorNotRegistered(self, s='', **kwargs):
notRegistered = conf.supybot.replies.notRegistered()
self.error(self.__makeReply(notRegistered, s), **kwargs)
v = conf.supybot.replies.notRegistered.get(self.msg.args[0])
self.error(self.__makeReply(v(), s), **kwargs)
def errorNoUser(self, s='', **kwargs):
noUser = conf.supybot.replies.noUser()
self.error(self.__makeReply(noUser, s), **kwargs)
v = conf.supybot.replies.noUser.get(self.msg.args[0])
self.error(self.__makeReply(v(), s), **kwargs)
def errorRequiresPrivacy(self, s='', **kwargs):
requiresPrivacy = conf.supybot.replies.requiresPrivacy()
self.error(self.__makeReply(requiresPrivacy, s), **kwargs)
v = conf.supybot.replies.requiresPrivacy.get(self.msg.args[0])
self.error(self.__makeReply(v(), s), **kwargs)
class IrcObjectProxy(RichReplyMethods):
@ -668,6 +695,8 @@ class Privmsg(irclib.IrcCallback):
if self.noIgnore or not ircdb.checkIgnored(msg.prefix,msg.args[0]):
self.__parent.__call__(irc, msg)
else:
# We want this to be under logging.DEBUG: it's not very useful,
# even for debugging things :)
self.log.log(0, 'Ignoring %s', msg.prefix)
else:
self.__parent.__call__(irc, msg)

View File

@ -81,7 +81,7 @@ be sent to the server if it requires one."""))
supybot.register('server', registry.String('irc.freenode.net', """Determines
what server the bot connects to."""))
supybot.register('channels', registry.CommaSeparatedListOfStrings('#supybot',
supybot.register('channels', registry.CommaSeparatedListOfStrings(['#supybot'],
"""Determines what channels the bot will join when it connects to the server.
"""))
@ -141,6 +141,11 @@ the snarf message."""))
# TODO: These should probably all be channel-specific.
supybot.registerGroup('reply')
supybot.reply.register('oneToOne', registry.Boolean(True, """Determines whether
the bot will send multi-message replies in a single messsage or in multiple
messages. For safety purposes (so the bot can't possibly flood) it will
normally send everything in a single message."""))
supybot.reply.register('errorInPrivate', registry.Boolean(False, """
Determines whether the bot will send error messages to users in private."""))
@ -211,49 +216,52 @@ why these default to what they do."""))
###
# Replies
###
# TODO: These should be channel-specific.
supybot.registerGroup('replies')
supybot.replies.register('error', registry.NormalizedString("""An error has
occurred and has been logged. Please contact this bot's administrator for more
information.""", """Determines what error message the bot gives when it wants
to be ambiguous."""))
supybot.replies.registerGroup('error', registry.GroupWithDefault(
registry.NormalizedString("""An error has occurred and has been logged.
Please contact this bot's administrator for more information.""", """
Determines what error message the bot gives when it wants to be
ambiguous.""")))
supybot.replies.register('noCapability', registry.NormalizedString("""You
don\'t have the %r capability. If you think that you should have this
capability, be sure that you are identified before trying again. The 'whoami'
command can tell you if you're identified.""", """Determines what error message
is given when the bot is telling someone they aren't cool enough to use the
command they tried to use."""))
supybot.replies.registerGroup('noCapability', registry.GroupWithDefault(
registry.NormalizedString("""You don't have the %r capability. If you
think that you should have this capability, be sure that you are identified
before trying again. The 'whoami' command can tell you if you're
identified.""", """Determines what error message is given when the bot is
telling someone they aren't cool enough to use the command they tried to
use.""")))
supybot.replies.register('success', registry.NormalizedString("""The operation
succeeded.""", """Determines what message the bot replies with when a command
succeeded."""))
supybot.replies.registerGroup('success', registry.GroupWithDefault(
registry.NormalizedString("""The operation succeeded.""", """Determines
what message the bot replies with when a command succeeded.""")))
supybot.replies.register('incorrectAuthentication',
registry.NormalizedString("""Your hostmask doesn't match or your password is
wrong.""", """Determines what message the bot replies wiwth when someone tries
to use a command that requires being identified or having a password and
neither credential is correct."""))
supybot.replies.registerGroup('incorrectAuthentication',
registry.GroupWithDefault(
registry.NormalizedString("""Your hostmask doesn't match or your password
is wrong.""", """Determines what message the bot replies with when someone
tries to use a command that requires being identified or having a password
and neither credential is correct.""")))
supybot.replies.register('noUser', registry.NormalizedString("""I can't find
that user in my user database.""", """Determines what error message the bot
replies with when someone tries to accessing some information on a user the
bot doesn't know about."""))
supybot.replies.registerGroup('noUser', registry.GroupWithDefault(
registry.NormalizedString("""I can't find that user in my user
database.""", """Determines what error message the bot replies with when
someone tries to accessing some information on a user the bot doesn't know
about.""")))
supybot.replies.register('notRegistered', registry.NormalizedString("""
You must be registered to use this command. If you are already registered, you
must either identify (using the identify command) or add a hostmask matching
your current hostmask (using the addhostmask command).""", """Determines what
error message the bot replies with when someone tries to do something that
requires them to be registered but they're not currently recognized."""))
supybot.replies.registerGroup('notRegistered', registry.GroupWithDefault(
registry.NormalizedString("""You must be registered to use this command.
If you are already registered, you must either identify (using the identify
command) or add a hostmask matching your current hostmask (using the
addhostmask command).""", """Determines what error message the bot replies
with when someone tries to do something that requires them to be registered
but they're not currently recognized.""")))
# XXX: removed replyInvalidArgument.
supybot.replies.registerGroup('requiresPrivacy', registry.GroupWithDefault(
registry.NormalizedString("""That operation cannot be done in a
channel.""", """Determines what error messages the bot sends to people who
try to do things in a channel that really should be done in private.""")))
supybot.replies.register('requiresPrivacy', registry.NormalizedString("""
That operation cannot be done in a channel.""", """Determines what error
messages the bot sends to people who try to do things in a channel that really
should be done in private."""))
supybot.replies.register('possibleBug', registry.NormalizedString("""This may
be a bug. If you think it is, please file a bug report at
<http://sourceforge.net/tracker/?func=add&group_id=58965&atid=489447>.""",

View File

@ -148,7 +148,7 @@ class IrcMsgQueue(object):
def enqueue(self, msg):
"""Enqueues a given message."""
if msg in self.msgs:
log.info('Not adding msg %s to queue' % msg)
log.warning('Not adding message %r to queue, already added.' % msg)
else:
self.msgs.add(msg)
if msg.command in _high:

View File

@ -138,6 +138,10 @@ class NormalizedString(String):
s = utils.normalizeWhitespace(s.strip())
String.set(self, s)
def setValue(self, s):
s = utils.normalizeWhitespace(s.strip())
String.setValue(self, s)
class StringSurroundedBySpaces(String):
def set(self, s):
String.set(self, s)
@ -180,6 +184,9 @@ class Group(object):
else:
self.__nonExistentEntry(original)
def get(self, attr):
return self.__getattr__(attr)
def getChild(self, attr):
return self.children[attr.lower()]
@ -251,10 +258,6 @@ class GroupWithValue(Group):
def __str__(self):
return str(self.value)
## def getValues(self, getChildren=False):
## L = Group.getValues(self, getChildren=False)
## L.insert(0, (self.getName(), str(self.value)))
## return L
class GroupWithDefault(GroupWithValue):
def __init__(self, value):
@ -267,19 +270,23 @@ class GroupWithDefault(GroupWithValue):
def __getattr__(self, attr):
try:
return Group.__getattr__(self, attr)
return GroupWithValue.__getattr__(self, attr)
except NonExistentRegistryEntry:
return self.value
self.__makeChild(attr, str(self))
return self.__getattr__(attr)
def setName(self, name):
Group.setName(self, name)
GroupWithValue.setName(self, name)
for (k, v) in cache.iteritems():
if k.startswith(self.name):
(_, group) = rsplit(k, '.', 1)
self.__makeChild(group, v)
def setChild(self, attr, s):
self.__setattr__(attr, s)
def getValues(self, getChildren=False):
L = GroupWithValue.getValues(self, getChildren)
me = str(self)
L = [v for v in L if str(v[1]) != me]
return L
if __name__ == '__main__':