From 58332ad382fb85b2b98e6bc89022d2578349b9f0 Mon Sep 17 00:00:00 2001 From: Jeremy Fincher Date: Wed, 21 Jan 2004 17:13:04 +0000 Subject: [PATCH] Added several new types for better error checking, converted supybot.channels to be space-separated, and made Admin.{join,nick} Do The Right Thing. --- src/Admin.py | 24 ++++++++++++++++++++++-- src/conf.py | 43 +++++++++++++++++++++++++++---------------- src/registry.py | 21 ++++++++++++++++----- 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/Admin.py b/src/Admin.py index 38ccb6f68..d73262e88 100755 --- a/src/Admin.py +++ b/src/Admin.py @@ -62,7 +62,18 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): self.joins = {} def do376(self, irc, msg): - irc.queueMsg(ircmsgs.joins(conf.supybot.channels())) + channels = conf.supybot.channels() + utils.sortBy(lambda s: ',' not in s, channels) + keys = [] + chans = [] + for channel in channels: + if ',' in channel: + (channel, key) = channel.split(',', 1) + chans.append(channel) + keys.append(key) + else: + chans.append(channel) + irc.queueMsg(ircmsgs.joins(channels, keys)) do422 = do377 = do376 def do471(self, irc, msg): @@ -128,6 +139,7 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): keys = [] channels = [] for channel in args: + original = channel if ',' in channel: (channel, key) = channel.split(',', 1) channels.insert(0, channel) @@ -137,6 +149,7 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): if not ircutils.isChannel(channel): irc.error('%r is not a valid channel.' % channel) return + conf.supybot.channels().append(original) irc.queueMsg(ircmsgs.joins(channels, keys)) for channel in channels: self.joins[channel] = (irc, msg) @@ -164,7 +177,11 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): Changes the bot's nick to .""" nick = privmsgs.getArgs(args) - irc.queueMsg(ircmsgs.nick(nick)) + if ircutils.isNick(nick): + conf.supybot.nick.setValue(nick) + irc.queueMsg(ircmsgs.nick(nick)) + else: + irc.error('That\'s not a valid nick.') def part(self, irc, msg, args): """ [ ...] @@ -178,6 +195,9 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg): if arg not in irc.state.channels: irc.error('I\'m not currently in %s' % arg) return + for arg in args: + if arg in conf.supybot.channels(): + conf.supybot.channels().remove(arg) irc.queueMsg(ircmsgs.parts(args, msg.nick)) def disable(self, irc, msg, args): diff --git a/src/conf.py b/src/conf.py index 44c05b0f8..9efe14d95 100644 --- a/src/conf.py +++ b/src/conf.py @@ -72,12 +72,20 @@ def registerGlobalValue(group, name, value): group.register(name, value) class ValidNick(registry.String): - def set(self, s): - original = getattr(self, 'value', self.default) - registry.String.set(self, s) - if not ircutils.isNick(self.value): - self.value = original - raise registry.InvalidRegistryValue, 'Value must be a valid nick.' + def setValue(self, v): + if not ircutils.isNick(v): + raise registry.InvalidRegistryValue, \ + 'Value must be a valid IRC nick.' + else: + registry.String.setValue(self, v) + +class ValidChannel(registry.String): + def setValue(self, v): + if not ircutils.isChannel(v): + raise registry.InvalidRegistryValue, \ + 'Value must be a valid IRC channel name.' + else: + registry.String.setValue(self, v) supybot.register('nick', ValidNick('supybot', """Determines the bot's nick.""")) @@ -95,9 +103,14 @@ 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'], -"""Determines what channels the bot will join when it connects to the server. -""")) +class SpaceSeparatedListOfChannels(registry.SeparatedListOf): + Value = ValidChannel + def splitter(self, s): + return s.split() + joiner = ' '.join + +supybot.register('channels', SpaceSeparatedListOfChannels(['#supybot'], """ +Determines what channels the bot will join when it connects to the server.""")) supybot.registerGroup('databases') supybot.databases.registerGroup('users') @@ -126,13 +139,11 @@ Refer to the Python documentation for the time module to see valid formatting characteres for time formats.""")) class IP(registry.String): - def set(self, s): - original = getattr(self, 'value', self.default) - registry.String.set(self, s) - if self.value: # Empty string is alright. - if not (utils.isIP(self.value) or utils.isIPV6(self.value)): - raise registry.InvalidRegistryValue, \ - 'Value must be a valid IP.' + def setValue(self, v): + if v and not (utils.isIP(v) or utils.isIPV6(v)): + raise registry.InvalidRegistryValue, 'Value must be a valid IP.' + else: + registry.String.setValue(self, v) supybot.register('externalIP', IP('', """A string that is the external IP of the bot. If this is the empty string, the bot will attempt to find out its IP diff --git a/src/registry.py b/src/registry.py index a0910a1a1..787f5ffc3 100644 --- a/src/registry.py +++ b/src/registry.py @@ -37,6 +37,7 @@ import sets import types import textwrap +import fix import utils class RegistryException(Exception): @@ -65,14 +66,20 @@ def open(filename): _cache[key.lower()] = value def close(registry, filename, annotated=True): + first = True + helpCache = sets.Set() fd = file(filename, 'w') for (name, value) in registry.getValues(getChildren=True): - if annotated and hasattr(value, 'help'): + if annotated and hasattr(value,'help') and value.help not in helpCache: + helpCache.add(value.help) lines = textwrap.wrap(value.help) for (i, line) in enumerate(lines): lines[i] = '# %s\n' % line lines.insert(0, '###\n') - lines.insert(0, '\n') + if first: + first = False + else: + lines.insert(0, '\n') lines.append('###\n') fd.writelines(lines) fd.write('%s: %s\n' % (name, value)) @@ -210,13 +217,17 @@ class SeparatedListOf(Value): def __str__(self): return self.joiner(self.value) - +class SpaceSeparatedListOfStrings(SeparatedListOf): + Value = String + def splitter(self, s): + return s.split(s) + joiner = ' '.join + class CommaSeparatedListOfStrings(SeparatedListOf): Value = String def splitter(self, s): return re.split(r'\s*,\s*', s) - def joiner(self, L): - return ','.join(L) + joiner = ', '.join class CommaSeparatedSetOfStrings(CommaSeparatedListOfStrings): def setValue(self, v):