Remove bracketSyntax, make brackets channel-specific.

This commit is contained in:
Jeremy Fincher 2004-05-07 16:14:02 +00:00
parent 6d1092957a
commit 8ab613dbed
4 changed files with 78 additions and 61 deletions

View File

@ -305,8 +305,9 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
return return
s = callbacks.addressed(irc.nick, msg) s = callbacks.addressed(irc.nick, msg)
if s: if s:
brackets = conf.supybot.reply.brackets.get(msg.args[0])()
try: try:
tokens = callbacks.tokenize(s) tokens = callbacks.tokenize(s, brackets=brackets)
if tokens and isinstance(tokens[0], list): if tokens and isinstance(tokens[0], list):
s = 'The command called may not be the result ' \ s = 'The command called may not be the result ' \
'of a nested command.' 'of a nested command.'

View File

@ -242,24 +242,21 @@ class Tokenizer:
token = lexer.get_token() token = lexer.get_token()
if not token: if not token:
break break
elif token == '|' and conf.supybot.pipeSyntax(): elif token == '|' and conf.supybot.reply.pipeSyntax():
if not args: if not args:
raise SyntaxError, '"|" with nothing preceding. I ' \ raise SyntaxError, '"|" with nothing preceding. I ' \
'obviously can\'t do a pipe with ' \ 'obviously can\'t do a pipe with ' \
'nothing before the |.' 'nothing before the |.'
ends.append(args) ends.append(args)
args = [] args = []
elif conf.supybot.bracketSyntax(): elif token == self.left:
if token == self.left: args.append(self._insideBrackets(lexer))
args.append(self._insideBrackets(lexer)) elif token == self.right:
elif token == self.right: raise SyntaxError, 'Spurious "%s". You may want to ' \
raise SyntaxError, 'Spurious "%s". You may want to ' \ 'quote your arguments with double ' \
'quote your arguments with double ' \ 'quotes in order to prevent extra ' \
'quotes in order to prevent extra ' \ 'brackets from being evaluated ' \
'brackets from being evaluated ' \ 'as nested commands.' % self.right
'as nested commands.' % self.right
else:
args.append(self._handleToken(token))
else: else:
args.append(self._handleToken(token)) args.append(self._handleToken(token))
if ends: if ends:
@ -272,14 +269,14 @@ class Tokenizer:
args[-1].append(ends.pop()) args[-1].append(ends.pop())
return args return args
def tokenize(s): def tokenize(s, brackets=None):
"""A utility function to create a Tokenizer and tokenize a string.""" """A utility function to create a Tokenizer and tokenize a string."""
start = time.time() start = time.time()
try: try:
tokens = '' tokens = brackets
if conf.supybot.bracketSyntax(): if brackets is None:
tokens = conf.supybot.brackets() tokens = conf.supybot.reply.brackets()
if conf.supybot.pipeSyntax(): if conf.supybot.reply.pipeSyntax():
tokens = '%s|' % tokens tokens = '%s|' % tokens
return Tokenizer(tokens).tokenize(s) return Tokenizer(tokens).tokenize(s)
except ValueError, e: except ValueError, e:

View File

@ -133,11 +133,13 @@ class ValidChannel(registry.String):
supybot.register('nick', ValidNick('supybot', supybot.register('nick', ValidNick('supybot',
"""Determines the bot's nick.""")) """Determines the bot's nick."""))
supybot.register('ident', ValidNick('supybot', registerGlobalValue(supybot, 'ident',
"""Determines the bot's ident.""")) ValidNick('supybot', """Determines the bot's ident string, if the server
doesn't provide one by default."""))
supybot.register('user', registry.String('supybot', """Determines the user registerGlobalValue(supybot, 'user',
the bot sends to the server.""")) registry.String('Supybot %s' % version, """Determines the user the bot
sends to the server."""))
# TODO: Make this check for validity. # TODO: Make this check for validity.
supybot.register('server', registry.String('irc.freenode.net', """Determines supybot.register('server', registry.String('irc.freenode.net', """Determines
@ -239,35 +241,44 @@ registerGlobalValue(supybot, 'externalIP',
### ###
# Reply/error tweaking. # Reply/error tweaking.
### ###
supybot.register('reply') registerGroup(supybot, 'reply')
supybot.reply.register('truncate', registry.Boolean(False, """Determines
whether the bot will simply truncate messages instead of breaking up long
messages and using the 'more' command to get the remaining chunks."""))
supybot.reply.register('maximumMores', registry.PositiveInteger(50, """
Determines what the maximum number of chunks (for use with the 'more' command)
will be."""))
supybot.reply.register('oneToOne', registry.Boolean(True, """Determines whether registerChannelValue(supybot.reply, 'truncate',
the bot will send multi-message replies in a single messsage or in multiple registry.Boolean(False, """Determines whether the bot will simply truncate
messages. For safety purposes (so the bot can't possibly flood) it will messages instead of breaking up long messages and using the 'more' command
normally send everything in a single message.""")) to get the remaining chunks."""))
supybot.register('bracketSyntax', registry.Boolean(True, """Supybot allows registerChannelValue(supybot.reply, 'maximumMores',
nested commands. If this option is enabled users can nest commands using a registry.PositiveInteger(50, """Determines what the maximum number of
bracket syntax, for example: 'bot: bar [foo]'.""")) chunks (for use with the 'more' command) will be."""))
registerGlobalValue(supybot.reply, '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."""))
registerChannelValue(supybot.reply, 'bracketSyntax',
registry.Boolean(True, """Supybot allows nested commands. If this option is
enabled, users can nest commands using a bracket syntax, for example: 'bot:
bar [foo]'. The matching left/right characters used for nesting commands
can be set via the supybot.reply.brackets"""))
class ValidBrackets(registry.OnlySomeStrings): class ValidBrackets(registry.OnlySomeStrings):
validStrings = ('', '[]', '<>', '{}', '()') validStrings = ('', '[]', '<>', '{}', '()')
supybot.register('brackets', ValidBrackets('[]', """Supybot allows you to registerChannelValue(supybot.reply, 'brackets',
specify what brackets are used for your nested commands. Valid sets of ValidBrackets('[]', """Supybot allows you to specify what brackets are used
brackets include [], <>, and {} (). [] has strong historical motivation, as for your nested commands. Valid sets of brackets include [], <>, and {}
well as being the brackets that don't require shift. <> or () might be (). [] has strong historical motivation, as well as being the brackets
slightly superior because they cannot occur in a nick.""")) that don't require shift. <> or () might be slightly superior because they
cannot occur in a nick. If this value is set to the empty string, no
nesting will be allowed."""))
supybot.register('pipeSyntax', registry.Boolean(False, """Supybot allows registerChannelValue(supybot.reply, 'pipeSyntax',
nested commands. Enabling this option will allow nested commands with a syntax registry.Boolean(False, """Supybot allows nested commands. Enabling this
similar to UNIX pipes, for example: 'bot: foo | bar'.""")) option will allow nested commands with a syntax similar to UNIX pipes, for
example: 'bot: foo | bar'."""))
supybot.reply.register('whenNotCommand', registry.Boolean(True, """ supybot.reply.register('whenNotCommand', registry.Boolean(True, """
Determines whether the bot will reply with an error message when it is Determines whether the bot will reply with an error message when it is
@ -434,21 +445,6 @@ over your modifications. Do note that if you change this to False inside the
bot, your changes won't be flushed. To make this change permanent, you must bot, your changes won't be flushed. To make this change permanent, you must
edit the registry yourself.""")) edit the registry yourself."""))
class SocketTimeout(registry.PositiveInteger):
def setValue(self, v):
registry.PositiveInteger.setValue(self, v)
socket.setdefaulttimeout(self.value)
supybot.register('defaultSocketTimeout', SocketTimeout(10, """Determines what
the default timeout for socket objects will be. This means that *all* sockets
will timeout when this many seconds has gone by (unless otherwise modified by
the author of the code that uses the sockets)."""))
supybot.register('pidFile', registry.String('', """Determines what file the bot
should write its PID (Process ID) to, so you can kill it more easily. If it's
left unset (as is the default) then no PID file will be written. A restart is
required for changes to this variable to take effect."""))
### ###
# supybot.drivers. For stuff relating to Supybot's drivers (duh!) # supybot.drivers. For stuff relating to Supybot's drivers (duh!)
### ###
@ -486,7 +482,7 @@ registerGlobalValue(supybot.directories, 'plugins',
'config supybot.directories.plugins [config supybot.directories.plugins], 'config supybot.directories.plugins [config supybot.directories.plugins],
newPluginDirectory'.""")) newPluginDirectory'."""))
supybot.register('plugins') # This will be used by plugins, but not here. registerGroup(supybot, 'plugins') # This will be used by plugins, but not here.
### ###
# supybot.databases. For stuff relating to Supybot's databases (duh!) # supybot.databases. For stuff relating to Supybot's databases (duh!)
@ -564,6 +560,30 @@ registerGlobalValue(supybot.protocols.http, 'peekSize',
found what it was looking for.""")) found what it was looking for."""))
###
# Especially boring stuff.
###
class SocketTimeout(registry.PositiveInteger):
"""Value must be an integer greater than supybot.drivers.poll and must be
greater than or equal to 1."""
def setValue(self, v):
if v < supybot.drivers.poll() or v < 1:
self.error()
registry.PositiveInteger.setValue(self, v)
socket.setdefaulttimeout(self.value)
registerGlobalValue(supybot, 'defaultSocketTimeout',
SocketTimeout(10, """Determines what the default timeout for socket objects
will be. This means that *all* sockets will timeout when this many seconds
has gone by (unless otherwise modified by the author of the code that uses
the sockets)."""))
registerGlobalValue(supybot, 'pidFile',
registry.String('', """Determines what file the bot should write its PID
(Process ID) to, so you can kill it more easily. If it's left unset (as is
the default) then no PID file will be written. A restart is required for
changes to this variable to take effect."""))
### ###
# Debugging options. # Debugging options.
### ###

View File

@ -109,7 +109,6 @@ def close(registry, filename, annotated=True, helpOnceOnly=False):
def isValidRegistryName(name): def isValidRegistryName(name):
return '.' not in name and ':' not in name and len(name.split()) == 1 return '.' not in name and ':' not in name and len(name.split()) == 1
class Group(object): class Group(object):
def __init__(self, supplyDefault=False): def __init__(self, supplyDefault=False):
self.name = 'unset' self.name = 'unset'