mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-23 19:22:45 +01:00
Internationalize callbacks.py, commands.py, and conf.py ; and generated the messages.pot
This commit is contained in:
parent
df3d096ab1
commit
6b26861c23
1011
locale/messages.pot
Normal file
1011
locale/messages.pot
Normal file
File diff suppressed because it is too large
Load Diff
@ -53,6 +53,8 @@ import supybot.ircmsgs as ircmsgs
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.registry as registry
|
||||
from supybot.utils.iter import any, all
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization()
|
||||
|
||||
def _addressed(nick, msg, prefixChars=None, nicks=None,
|
||||
prefixStrings=None, whenAddressedByNick=None,
|
||||
@ -179,7 +181,7 @@ def reply(msg, s, prefixNick=None, private=None,
|
||||
if error:
|
||||
notice =conf.get(conf.supybot.reply.error.withNotice, channel) or notice
|
||||
private=conf.get(conf.supybot.reply.error.inPrivate, channel) or private
|
||||
s = 'Error: ' + s
|
||||
s = _('Error: ') + s
|
||||
if private:
|
||||
prefixNick = False
|
||||
if to is None:
|
||||
@ -193,7 +195,7 @@ def reply(msg, s, prefixNick=None, private=None,
|
||||
# Ok, now let's make the payload:
|
||||
s = ircutils.safeArgument(s)
|
||||
if not s and not action:
|
||||
s = 'Error: I tried to send you an empty message.'
|
||||
s = _('Error: I tried to send you an empty message.')
|
||||
if prefixNick and ircutils.isChannel(target):
|
||||
# Let's may sure we don't do, "#channel: foo.".
|
||||
if not ircutils.isChannel(to):
|
||||
@ -283,11 +285,11 @@ class Tokenizer(object):
|
||||
while True:
|
||||
token = lexer.get_token()
|
||||
if not token:
|
||||
raise SyntaxError, 'Missing "%s". You may want to ' \
|
||||
'quote your arguments with double ' \
|
||||
'quotes in order to prevent extra ' \
|
||||
'brackets from being evaluated ' \
|
||||
'as nested commands.' % self.right
|
||||
raise SyntaxError, _('Missing "%s". You may want to '
|
||||
'quote your arguments with double '
|
||||
'quotes in order to prevent extra '
|
||||
'brackets from being evaluated '
|
||||
'as nested commands.') % self.right
|
||||
elif token == self.right:
|
||||
return ret
|
||||
elif token == self.left:
|
||||
@ -313,26 +315,26 @@ class Tokenizer(object):
|
||||
# for strings like 'foo | bar', where a pipe stands alone as a
|
||||
# token, but shouldn't be treated specially.
|
||||
if not args:
|
||||
raise SyntaxError, '"|" with nothing preceding. I ' \
|
||||
'obviously can\'t do a pipe with ' \
|
||||
'nothing before the |.'
|
||||
raise SyntaxError, _('"|" with nothing preceding. I '
|
||||
'obviously can\'t do a pipe with '
|
||||
'nothing before the |.')
|
||||
ends.append(args)
|
||||
args = []
|
||||
elif token == self.left:
|
||||
args.append(self._insideBrackets(lexer))
|
||||
elif token == self.right:
|
||||
raise SyntaxError, 'Spurious "%s". You may want to ' \
|
||||
'quote your arguments with double ' \
|
||||
'quotes in order to prevent extra ' \
|
||||
'brackets from being evaluated ' \
|
||||
'as nested commands.' % self.right
|
||||
raise SyntaxError, _('Spurious "%s". You may want to '
|
||||
'quote your arguments with double '
|
||||
'quotes in order to prevent extra '
|
||||
'brackets from being evaluated '
|
||||
'as nested commands.') % self.right
|
||||
else:
|
||||
args.append(self._handleToken(token))
|
||||
if ends:
|
||||
if not args:
|
||||
raise SyntaxError, '"|" with nothing following. I ' \
|
||||
'obviously can\'t do a pipe with ' \
|
||||
'nothing after the |.'
|
||||
raise SyntaxError, _('"|" with nothing following. I '
|
||||
'obviously can\'t do a pipe with '
|
||||
'nothing after the |.')
|
||||
args.append(ends.pop())
|
||||
while ends:
|
||||
args[-1].append(ends.pop())
|
||||
@ -510,9 +512,9 @@ class RichReplyMethods(object):
|
||||
given = _repr(given)
|
||||
else:
|
||||
given = '"%s"' % given
|
||||
v = '%s is not a valid %s.' % (given, what)
|
||||
v = _('%s is not a valid %s.') % (given, what)
|
||||
else:
|
||||
v = 'That\'s not a valid %s.' % what
|
||||
v = _('That\'s not a valid %s.') % what
|
||||
if 'Raise' not in kwargs:
|
||||
kwargs['Raise'] = True
|
||||
return self._error(self.__makeReply(v, s), **kwargs)
|
||||
@ -590,8 +592,8 @@ class NestedCommandsIrcProxy(ReplyIrcProxy):
|
||||
if maxNesting and self.nested > maxNesting:
|
||||
log.warning('%s attempted more than %s levels of nesting.',
|
||||
self.msg.prefix, maxNesting)
|
||||
return self.error('You\'ve attempted more nesting than is '
|
||||
'currently allowed on this bot.')
|
||||
return self.error(_('You\'ve attempted more nesting than is '
|
||||
'currently allowed on this bot.'))
|
||||
# The deepcopy here is necessary for Scheduler; it re-runs already
|
||||
# tokenized commands. There's a possibility a simple copy[:] would
|
||||
# work, but we're being careful.
|
||||
@ -769,10 +771,10 @@ class NestedCommandsIrcProxy(ReplyIrcProxy):
|
||||
elif len(cbs) > 1:
|
||||
names = sorted([cb.name() for cb in cbs])
|
||||
command = formatCommand(command)
|
||||
self.error(format('The command %q is available in the %L '
|
||||
self.error(format(_('The command %q is available in the %L '
|
||||
'plugins. Please specify the plugin '
|
||||
'whose command you wish to call by using '
|
||||
'its name as a command before %q.',
|
||||
'its name as a command before %q.'),
|
||||
command, names, command))
|
||||
else:
|
||||
cb = cbs[0]
|
||||
@ -895,8 +897,11 @@ class NestedCommandsIrcProxy(ReplyIrcProxy):
|
||||
return
|
||||
response = msgs.pop()
|
||||
if msgs:
|
||||
n = ircutils.bold('(%s)')
|
||||
n %= format('%n', (len(msgs), 'more', 'message'))
|
||||
if len(msgs) == 1:
|
||||
more = _('more message')
|
||||
else:
|
||||
more = _('more messages')
|
||||
n = ircutils.bold('(%i %s)' % (len(msgs), more))
|
||||
response = '%s %s' % (response, n)
|
||||
prefix = msg.prefix
|
||||
if self.to and ircutils.isNick(self.to):
|
||||
@ -995,9 +1000,9 @@ class Disabled(registry.SpaceSeparatedListOf):
|
||||
List = CanonicalNameSet
|
||||
|
||||
conf.registerGlobalValue(conf.supybot.commands, 'disabled',
|
||||
Disabled([], """Determines what commands are currently disabled. Such
|
||||
Disabled([], _("""Determines what commands are currently disabled. Such
|
||||
commands will not appear in command lists, etc. They will appear not even
|
||||
to exist."""))
|
||||
to exist.""")))
|
||||
|
||||
class DisabledCommands(object):
|
||||
def __init__(self):
|
||||
@ -1186,7 +1191,7 @@ class Commands(BasePlugin):
|
||||
utils.exnToString(e))
|
||||
help = self.getCommandHelp(command)
|
||||
if help.endswith('command has no help.'):
|
||||
irc.error('Invalid arguments for %s.' % method.__name__)
|
||||
irc.error(_('Invalid arguments for %s.') % method.__name__)
|
||||
else:
|
||||
irc.reply(help)
|
||||
except (SyntaxError, Error), e:
|
||||
@ -1212,7 +1217,8 @@ class Commands(BasePlugin):
|
||||
if hasattr(method, '__doc__'):
|
||||
return help(method, name=formatCommand(command))
|
||||
else:
|
||||
return format('The %q command has no help.',formatCommand(command))
|
||||
return format(_('The %q command has no help.'),
|
||||
formatCommand(command))
|
||||
|
||||
class PluginMixin(BasePlugin, irclib.IrcCallback):
|
||||
public = True
|
||||
|
@ -46,6 +46,8 @@ import supybot.ircdb as ircdb
|
||||
import supybot.ircmsgs as ircmsgs
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.callbacks as callbacks
|
||||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization()
|
||||
|
||||
|
||||
###
|
||||
@ -166,7 +168,7 @@ def _int(s):
|
||||
else:
|
||||
raise
|
||||
|
||||
def getInt(irc, msg, args, state, type='integer', p=None):
|
||||
def getInt(irc, msg, args, state, type=_('integer'), p=None):
|
||||
try:
|
||||
i = _int(args[0])
|
||||
if p is not None:
|
||||
@ -177,7 +179,7 @@ def getInt(irc, msg, args, state, type='integer', p=None):
|
||||
except ValueError:
|
||||
state.errorInvalid(type, args[0])
|
||||
|
||||
def getNonInt(irc, msg, args, state, type='non-integer value'):
|
||||
def getNonInt(irc, msg, args, state, type=_('non-integer value')):
|
||||
try:
|
||||
i = _int(args[0])
|
||||
state.errorInvalid(type, args[0])
|
||||
@ -188,7 +190,7 @@ def getLong(irc, msg, args, state, type='long'):
|
||||
getInt(irc, msg, args, state, type)
|
||||
state.args[-1] = long(state.args[-1])
|
||||
|
||||
def getFloat(irc, msg, args, state, type='floating point number'):
|
||||
def getFloat(irc, msg, args, state, type=_('floating point number')):
|
||||
try:
|
||||
state.args.append(float(args[0]))
|
||||
del args[0]
|
||||
@ -197,14 +199,14 @@ def getFloat(irc, msg, args, state, type='floating point number'):
|
||||
|
||||
def getPositiveInt(irc, msg, args, state, *L):
|
||||
getInt(irc, msg, args, state,
|
||||
p=lambda i: i>0, type='positive integer', *L)
|
||||
p=lambda i: i>0, type=_('positive integer') *L)
|
||||
|
||||
def getNonNegativeInt(irc, msg, args, state, *L):
|
||||
getInt(irc, msg, args, state,
|
||||
p=lambda i: i>=0, type='non-negative integer', *L)
|
||||
p=lambda i: i>=0, type=_('non-negative integer'), *L)
|
||||
|
||||
def getIndex(irc, msg, args, state):
|
||||
getInt(irc, msg, args, state, type='index')
|
||||
getInt(irc, msg, args, state, type=_('index'))
|
||||
if state.args[-1] > 0:
|
||||
state.args[-1] -= 1
|
||||
|
||||
@ -229,14 +231,14 @@ def getExpiry(irc, msg, args, state):
|
||||
state.args.append(expires)
|
||||
del args[0]
|
||||
except ValueError:
|
||||
state.errorInvalid('number of seconds', args[0])
|
||||
state.errorInvalid(_('number of seconds'), args[0])
|
||||
|
||||
def getBoolean(irc, msg, args, state):
|
||||
try:
|
||||
state.args.append(utils.str.toBool(args[0]))
|
||||
del args[0]
|
||||
except ValueError:
|
||||
state.errorInvalid('boolean', args[0])
|
||||
state.errorInvalid(_('boolean'), args[0])
|
||||
|
||||
def getNetworkIrc(irc, msg, args, state, errorIfNoMatch=False):
|
||||
if args:
|
||||
@ -250,13 +252,13 @@ def getNetworkIrc(irc, msg, args, state, errorIfNoMatch=False):
|
||||
else:
|
||||
state.args.append(irc)
|
||||
|
||||
def getHaveOp(irc, msg, args, state, action='do that'):
|
||||
def getHaveOp(irc, msg, args, state, action=_('do that')):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error('I\'m not even in %s.' % state.channel, Raise=True)
|
||||
state.error(_('I\'m not even in %s.') % state.channel, Raise=True)
|
||||
if not irc.state.channels[state.channel].isOp(irc.nick):
|
||||
state.error('I need to be opped to %s.' % action, Raise=True)
|
||||
state.error(_('I need to be opped to %s.') % action, Raise=True)
|
||||
|
||||
def validChannel(irc, msg, args, state):
|
||||
if irc.isChannel(args[0]):
|
||||
@ -273,7 +275,7 @@ def getHostmask(irc, msg, args, state):
|
||||
state.args.append(hostmask)
|
||||
del args[0]
|
||||
except KeyError:
|
||||
state.errorInvalid('nick or hostmask', args[0])
|
||||
state.errorInvalid(_('nick or hostmask'), args[0])
|
||||
|
||||
def getBanmask(irc, msg, args, state):
|
||||
getHostmask(irc, msg, args, state)
|
||||
@ -325,10 +327,10 @@ def _getRe(f):
|
||||
else:
|
||||
state.args.append(s)
|
||||
else:
|
||||
state.errorInvalid('regular expression', s)
|
||||
state.errorInvalid(_('regular expression'), s)
|
||||
except IndexError:
|
||||
args[:] = original
|
||||
state.errorInvalid('regular expression', s)
|
||||
state.errorInvalid(_('regular expression'), s)
|
||||
return get
|
||||
|
||||
getMatcher = _getRe(utils.str.perlReToPythonRe)
|
||||
@ -339,7 +341,7 @@ def getNick(irc, msg, args, state):
|
||||
if 'nicklen' in irc.state.supported:
|
||||
if len(args[0]) > irc.state.supported['nicklen']:
|
||||
state.errorInvalid('nick', args[0],
|
||||
'That nick is too long for this server.')
|
||||
_('That nick is too long for this server.'))
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
state.errorInvalid('nick', args[0])
|
||||
@ -388,12 +390,12 @@ def inChannel(irc, msg, args, state):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error('I\'m not in %s.' % state.channel, Raise=True)
|
||||
state.error(_('I\'m not in %s.') % state.channel, Raise=True)
|
||||
|
||||
def onlyInChannel(irc, msg, args, state):
|
||||
if not (irc.isChannel(msg.args[0]) and msg.args[0] in irc.state.channels):
|
||||
state.error('This command may only be given in a channel that I am in.',
|
||||
Raise=True)
|
||||
state.error(_('This command may only be given in a channel that I am '
|
||||
'in.'), Raise=True)
|
||||
else:
|
||||
state.channel = msg.args[0]
|
||||
state.args.append(state.channel)
|
||||
@ -405,18 +407,18 @@ def callerInGivenChannel(irc, msg, args, state):
|
||||
if msg.nick in irc.state.channels[channel].users:
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
state.error('You must be in %s.' % channel, Raise=True)
|
||||
state.error(_('You must be in %s.') % channel, Raise=True)
|
||||
else:
|
||||
state.error('I\'m not in %s.' % channel, Raise=True)
|
||||
state.error(_('I\'m not in %s.') % channel, Raise=True)
|
||||
else:
|
||||
state.errorInvalid('channel', args[0])
|
||||
state.errorInvalid(_('channel'), args[0])
|
||||
|
||||
def nickInChannel(irc, msg, args, state):
|
||||
originalArgs = state.args[:]
|
||||
inChannel(irc, msg, args, state)
|
||||
state.args = originalArgs
|
||||
if args[0] not in irc.state.channels[state.channel].users:
|
||||
state.error('%s is not in %s.' % (args[0], state.channel), Raise=True)
|
||||
state.error(_('%s is not in %s.') % (args[0], state.channel), Raise=True)
|
||||
state.args.append(args.pop(0))
|
||||
|
||||
def getChannelOrNone(irc, msg, args, state):
|
||||
@ -450,7 +452,7 @@ def getSomething(irc, msg, args, state, errorMsg=None, p=None):
|
||||
p = lambda _: True
|
||||
if not args[0] or not p(args[0]):
|
||||
if errorMsg is None:
|
||||
errorMsg = 'You must not give the empty string as an argument.'
|
||||
errorMsg = _('You must not give the empty string as an argument.')
|
||||
state.error(errorMsg, Raise=True)
|
||||
else:
|
||||
state.args.append(args.pop(0))
|
||||
@ -467,7 +469,7 @@ def private(irc, msg, args, state):
|
||||
def public(irc, msg, args, state, errmsg=None):
|
||||
if not irc.isChannel(msg.args[0]):
|
||||
if errmsg is None:
|
||||
errmsg = 'This message must be sent in a channel.'
|
||||
errmsg = _('This message must be sent in a channel.')
|
||||
state.error(errmsg, Raise=True)
|
||||
|
||||
def checkCapability(irc, msg, args, state, cap):
|
||||
@ -508,14 +510,14 @@ def getHttpUrl(irc, msg, args, state):
|
||||
elif utils.web.httpUrlRe.match('http://' + args[0]):
|
||||
state.args.append('http://' + args.pop(0))
|
||||
else:
|
||||
state.errorInvalid('http url', args[0])
|
||||
state.errorInvalid(_('http url'), args[0])
|
||||
|
||||
def getNow(irc, msg, args, state):
|
||||
state.args.append(int(time.time()))
|
||||
|
||||
def getCommandName(irc, msg, args, state):
|
||||
if ' ' in args[0]:
|
||||
state.errorInvalid('command name', args[0])
|
||||
state.errorInvalid(_('command name'), args[0])
|
||||
else:
|
||||
state.args.append(callbacks.canonicalName(args.pop(0)))
|
||||
|
||||
@ -523,13 +525,13 @@ def getIp(irc, msg, args, state):
|
||||
if utils.net.isIP(args[0]):
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
state.errorInvalid('ip', args[0])
|
||||
state.errorInvalid(_('ip'), args[0])
|
||||
|
||||
def getLetter(irc, msg, args, state):
|
||||
if len(args[0]) == 1:
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
state.errorInvalid('letter', args[0])
|
||||
state.errorInvalid(_('letter'), args[0])
|
||||
|
||||
def getMatch(irc, msg, args, state, regexp, errmsg):
|
||||
m = regexp.search(args[0])
|
||||
@ -561,7 +563,7 @@ def getPlugin(irc, msg, args, state, require=True):
|
||||
state.args.append(cb)
|
||||
del args[0]
|
||||
elif require:
|
||||
state.errorInvalid('plugin', args[0])
|
||||
state.errorInvalid(_('plugin'), args[0])
|
||||
else:
|
||||
state.args.append(None)
|
||||
|
||||
@ -569,7 +571,7 @@ def getIrcColor(irc, msg, args, state):
|
||||
if args[0] in ircutils.mircColors:
|
||||
state.args.append(ircutils.mircColors[args.pop(0)])
|
||||
else:
|
||||
state.errorInvalid('irc color')
|
||||
state.errorInvalid(_('irc color'))
|
||||
|
||||
def getText(irc, msg, args, state):
|
||||
if args:
|
||||
|
500
src/conf.py
500
src/conf.py
@ -36,6 +36,8 @@ import socket
|
||||
import supybot.utils as utils
|
||||
import supybot.registry as registry
|
||||
import supybot.ircutils as ircutils
|
||||
from supybot.i18n import PluginInternationalization
|
||||
_ = PluginInternationalization()
|
||||
|
||||
###
|
||||
# version: This should be pretty obvious.
|
||||
@ -99,12 +101,12 @@ def registerChannelValue(group, name, value):
|
||||
|
||||
def registerPlugin(name, currentValue=None, public=True):
|
||||
group = registerGlobalValue(supybot.plugins, name,
|
||||
registry.Boolean(False, """Determines whether this plugin is loaded by
|
||||
default.""", showDefault=False))
|
||||
registry.Boolean(False, _("""Determines whether this plugin is loaded
|
||||
bydefault."""), showDefault=False))
|
||||
supybot.plugins().add(name)
|
||||
registerGlobalValue(group, 'public',
|
||||
registry.Boolean(public, """Determines whether this plugin is
|
||||
publicly visible."""))
|
||||
registry.Boolean(public, _("""Determines whether this plugin is
|
||||
publicly visible.""")))
|
||||
if currentValue is not None:
|
||||
supybot.plugins.get(name).setValue(currentValue)
|
||||
registerGroup(users.plugins, name)
|
||||
@ -189,18 +191,18 @@ class ValidHostmask(registry.String):
|
||||
super(ValidHostmask, self).setValue(v)
|
||||
|
||||
registerGlobalValue(supybot, 'nick',
|
||||
ValidNick('supybot', """Determines the bot's default nick."""))
|
||||
ValidNick('supybot', _("""Determines the bot's default nick.""")))
|
||||
|
||||
registerGlobalValue(supybot.nick, 'alternates',
|
||||
ValidNicksAllowingPercentS(['%s`', '%s_'], """Determines what alternative
|
||||
ValidNicksAllowingPercentS(['%s`', '%s_'], _("""Determines what alternative
|
||||
nicks will be used if the primary nick (supybot.nick) isn't available. A
|
||||
%s in this nick is replaced by the value of supybot.nick when used. If no
|
||||
alternates are given, or if all are used, the supybot.nick will be perturbed
|
||||
appropriately until an unused nick is found."""))
|
||||
appropriately until an unused nick is found.""")))
|
||||
|
||||
registerGlobalValue(supybot, 'ident',
|
||||
ValidNick('supybot', """Determines the bot's ident string, if the server
|
||||
doesn't provide one by default."""))
|
||||
ValidNick('supybot', _("""Determines the bot's ident string, if the server
|
||||
doesn't provide one by default.""")))
|
||||
|
||||
class VersionIfEmpty(registry.String):
|
||||
def __call__(self):
|
||||
@ -210,15 +212,15 @@ class VersionIfEmpty(registry.String):
|
||||
return ret
|
||||
|
||||
registerGlobalValue(supybot, 'user',
|
||||
VersionIfEmpty('', """Determines the user the bot sends to the server.
|
||||
VersionIfEmpty('', _("""Determines the user the bot sends to the server.
|
||||
A standard user using the current version of the bot will be generated if
|
||||
this is left empty."""))
|
||||
this is left empty.""")))
|
||||
|
||||
class Networks(registry.SpaceSeparatedSetOfStrings):
|
||||
List = ircutils.IrcSet
|
||||
|
||||
registerGlobalValue(supybot, 'networks',
|
||||
Networks([], """Determines what networks the bot will connect to.""",
|
||||
Networks([], _("""Determines what networks the bot will connect to."""),
|
||||
orderAlphabetically=True))
|
||||
|
||||
class Servers(registry.SpaceSeparatedListOfStrings):
|
||||
@ -259,20 +261,22 @@ class SpaceSeparatedSetOfChannels(registry.SpaceSeparatedListOf):
|
||||
def registerNetwork(name, password='', ssl=False):
|
||||
network = registerGroup(supybot.networks, name)
|
||||
registerGlobalValue(network, 'password', registry.String(password,
|
||||
"""Determines what password will be used on %s. Yes, we know that
|
||||
_("""Determines what password will be used on %s. Yes, we know that
|
||||
technically passwords are server-specific and not network-specific,
|
||||
but this is the best we can do right now.""" % name, private=True))
|
||||
but this is the best we can do right now.""") % name, private=True))
|
||||
registryServers = registerGlobalValue(network, 'servers', Servers([],
|
||||
"""Determines what servers the bot will connect to for %s. Each will
|
||||
_("""Determines what servers the bot will connect to for %s. Each will
|
||||
be tried in order, wrapping back to the first when the cycle is
|
||||
completed.""" % name))
|
||||
completed.""") % name))
|
||||
registerGlobalValue(network, 'channels', SpaceSeparatedSetOfChannels([],
|
||||
"""Determines what channels the bot will join only on %s.""" % name))
|
||||
_("""Determines what channels the bot will join only on %s.""") %
|
||||
name))
|
||||
registerGlobalValue(network, 'ssl', registry.Boolean(ssl,
|
||||
"""Determines whether the bot will attempt to connect with SSL sockets
|
||||
to %s.""" % name))
|
||||
_("""Determines whether the bot will attempt to connect with SSL
|
||||
sockets to %s.""") % name))
|
||||
registerChannelValue(network.channels, 'key', registry.String('',
|
||||
"""Determines what key (if any) will be used to join the channel."""))
|
||||
_("""Determines what key (if any) will be used to join the
|
||||
channel.""")))
|
||||
return network
|
||||
|
||||
# Let's fill our networks.
|
||||
@ -291,10 +295,10 @@ registerGroup(supybot, 'reply')
|
||||
|
||||
registerGroup(supybot.reply, 'format')
|
||||
registerChannelValue(supybot.reply.format, 'time',
|
||||
registry.String('%I:%M %p, %B %d, %Y', """Determines how timestamps printed
|
||||
for human reading should be formatted. Refer to the Python documentation
|
||||
for the time module to see valid formatting characters for time
|
||||
formats."""))
|
||||
registry.String('%I:%M %p, %B %d, %Y', _("""Determines how timestamps
|
||||
printed for human reading should be formatted. Refer to the Python
|
||||
documentation for the time module to see valid formatting characters for
|
||||
time formats.""")))
|
||||
def timestamp(t):
|
||||
if t is None:
|
||||
t = time.time()
|
||||
@ -305,8 +309,8 @@ utils.str.timestamp = timestamp
|
||||
|
||||
registerGroup(supybot.reply.format.time, 'elapsed')
|
||||
registerChannelValue(supybot.reply.format.time.elapsed, 'short',
|
||||
registry.Boolean(False, """Determines whether elapsed times will be given
|
||||
as "1 day, 2 hours, 3 minutes, and 15 seconds" or as "1d 2h 3m 15s"."""))
|
||||
registry.Boolean(False, _("""Determines whether elapsed times will be given
|
||||
as "1 day, 2 hours, 3 minutes, and 15 seconds" or as "1d 2h 3m 15s".""")))
|
||||
|
||||
originalTimeElapsed = utils.timeElapsed
|
||||
def timeElapsed(*args, **kwargs):
|
||||
@ -315,116 +319,117 @@ def timeElapsed(*args, **kwargs):
|
||||
utils.timeElapsed = timeElapsed
|
||||
|
||||
registerGlobalValue(supybot.reply, 'maximumLength',
|
||||
registry.Integer(512*256, """Determines the absolute maximum length of the
|
||||
bot's reply -- no reply will be passed through the bot with a length
|
||||
greater than this."""))
|
||||
registry.Integer(512*256, _("""Determines the absolute maximum length of
|
||||
the bot's reply -- no reply will be passed through the bot with a length
|
||||
greater than this.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'mores',
|
||||
registry.Boolean(True, """Determines whether the bot will break up long
|
||||
registry.Boolean(True, _("""Determines whether the bot will break up long
|
||||
messages into chunks and allow users to use the 'more' command to get the
|
||||
remaining chunks."""))
|
||||
remaining chunks.""")))
|
||||
|
||||
registerChannelValue(supybot.reply.mores, 'maximum',
|
||||
registry.PositiveInteger(50, """Determines what the maximum number of
|
||||
chunks (for use with the 'more' command) will be."""))
|
||||
registry.PositiveInteger(50, _("""Determines what the maximum number of
|
||||
chunks (for use with the 'more' command) will be.""")))
|
||||
|
||||
registerChannelValue(supybot.reply.mores, 'length',
|
||||
registry.NonNegativeInteger(0, """Determines how long individual chunks
|
||||
registry.NonNegativeInteger(0, _("""Determines how long individual chunks
|
||||
will be. If set to 0, uses our super-tweaked,
|
||||
get-the-most-out-of-an-individual-message default."""))
|
||||
get-the-most-out-of-an-individual-message default.""")))
|
||||
|
||||
registerChannelValue(supybot.reply.mores, 'instant',
|
||||
registry.PositiveInteger(1, """Determines how many mores will be sent
|
||||
registry.PositiveInteger(1, _("""Determines how many mores will be sent
|
||||
instantly (i.e., without the use of the more command, immediately when
|
||||
they are formed). Defaults to 1, which means that a more command will be
|
||||
required for all but the first chunk."""))
|
||||
required for all but the first chunk.""")))
|
||||
|
||||
registerGlobalValue(supybot.reply, 'oneToOne',
|
||||
registry.Boolean(True, """Determines whether the bot will send
|
||||
registry.Boolean(True, _("""Determines whether the bot will send
|
||||
multi-message replies in a single message or in multiple messages. For
|
||||
safety purposes (so the bot is less likely to flood) it will normally send
|
||||
everything in a single message, using mores if necessary."""))
|
||||
everything in a single message, using mores if necessary.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'whenNotCommand',
|
||||
registry.Boolean(True, """Determines whether the bot will reply with an
|
||||
registry.Boolean(True, _("""Determines whether the bot will reply with an
|
||||
error message when it is addressed but not given a valid command. If this
|
||||
value is False, the bot will remain silent, as long as no other plugins
|
||||
override the normal behavior."""))
|
||||
override the normal behavior.""")))
|
||||
|
||||
registerGroup(supybot.reply, 'error')
|
||||
registerGlobalValue(supybot.reply.error, 'detailed',
|
||||
registry.Boolean(False, """Determines whether error messages that result
|
||||
registry.Boolean(False, _("""Determines whether error messages that result
|
||||
from bugs in the bot will show a detailed error message (the uncaught
|
||||
exception) or a generic error message."""))
|
||||
exception) or a generic error message.""")))
|
||||
registerChannelValue(supybot.reply.error, 'inPrivate',
|
||||
registry.Boolean(False, """Determines whether the bot will send error
|
||||
registry.Boolean(False, _("""Determines whether the bot will send error
|
||||
messages to users in private. You might want to do this in order to keep
|
||||
channel traffic to minimum. This can be used in combination with
|
||||
supybot.reply.error.withNotice."""))
|
||||
supybot.reply.error.withNotice.""")))
|
||||
registerChannelValue(supybot.reply.error, 'withNotice',
|
||||
registry.Boolean(False, """Determines whether the bot will send error
|
||||
registry.Boolean(False, _("""Determines whether the bot will send error
|
||||
messages to users via NOTICE instead of PRIVMSG. You might want to do this
|
||||
so users can ignore NOTICEs from the bot and not have to see error
|
||||
messages; or you might want to use it in combination with
|
||||
supybot.reply.errorInPrivate so private errors don't open a query window
|
||||
in most IRC clients."""))
|
||||
in most IRC clients.""")))
|
||||
registerChannelValue(supybot.reply.error, 'noCapability',
|
||||
registry.Boolean(False, """Determines whether the bot will send an error
|
||||
registry.Boolean(False, _("""Determines whether the bot will send an error
|
||||
message to users who attempt to call a command for which they do not have
|
||||
the necessary capability. You may wish to make this True if you don't want
|
||||
users to understand the underlying security system preventing them from
|
||||
running certain commands."""))
|
||||
running certain commands.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'inPrivate',
|
||||
registry.Boolean(False, """Determines whether the bot will reply privately
|
||||
when replying in a channel, rather than replying to the whole channel."""))
|
||||
registry.Boolean(False, _("""Determines whether the bot will reply
|
||||
privatelywhen replying in a channel, rather than replying to the whole
|
||||
channel.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'withNotice',
|
||||
registry.Boolean(False, """Determines whether the bot will reply with a
|
||||
registry.Boolean(False, _("""Determines whether the bot will reply with a
|
||||
notice when replying in a channel, rather than replying with a privmsg as
|
||||
normal."""))
|
||||
normal.""")))
|
||||
|
||||
# XXX: User value.
|
||||
registerGlobalValue(supybot.reply, 'withNoticeWhenPrivate',
|
||||
registry.Boolean(False, """Determines whether the bot will reply with a
|
||||
registry.Boolean(False, _("""Determines whether the bot will reply with a
|
||||
notice when it is sending a private message, in order not to open a /query
|
||||
window in clients. This can be overridden by individual users via the user
|
||||
configuration variable reply.withNoticeWhenPrivate."""))
|
||||
configuration variable reply.withNoticeWhenPrivate.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'withNickPrefix',
|
||||
registry.Boolean(True, """Determines whether the bot will always prefix the
|
||||
user's nick to its reply to that user's command."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will always prefix
|
||||
theuser's nick to its reply to that user's command.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'whenNotAddressed',
|
||||
registry.Boolean(False, """Determines whether the bot should attempt to
|
||||
registry.Boolean(False, _("""Determines whether the bot should attempt to
|
||||
reply to all messages even if they don't address it (either via its nick
|
||||
or a prefix character). If you set this to True, you almost certainly want
|
||||
to set supybot.reply.whenNotCommand to False."""))
|
||||
to set supybot.reply.whenNotCommand to False.""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'requireChannelCommandsToBeSentInChannel',
|
||||
registry.Boolean(False, """Determines whether the bot will allow you to
|
||||
registry.Boolean(False, _("""Determines whether the bot will allow you to
|
||||
send channel-related commands outside of that channel. Sometimes people
|
||||
find it confusing if a channel-related command (like Filter.outfilter)
|
||||
changes the behavior of the channel but was sent outside the channel
|
||||
itself."""))
|
||||
itself.""")))
|
||||
|
||||
registerGlobalValue(supybot, 'followIdentificationThroughNickChanges',
|
||||
registry.Boolean(False, """Determines whether the bot will unidentify
|
||||
registry.Boolean(False, _("""Determines whether the bot will unidentify
|
||||
someone when that person changes his or her nick. Setting this to True
|
||||
will cause the bot to track such changes. It defaults to False for a
|
||||
little greater security."""))
|
||||
little greater security.""")))
|
||||
|
||||
registerGlobalValue(supybot, 'alwaysJoinOnInvite',
|
||||
registry.Boolean(False, """Determines whether the bot will always join a
|
||||
registry.Boolean(False, _("""Determines whether the bot will always join a
|
||||
channel when it's invited. If this value is False, the bot will only join
|
||||
a channel if the user inviting it has the 'admin' capability (or if it's
|
||||
explicitly told to join the channel using the Admin.join command)"""))
|
||||
explicitly told to join the channel using the Admin.join command)""")))
|
||||
|
||||
registerChannelValue(supybot.reply, 'showSimpleSyntax',
|
||||
registry.Boolean(False, """Supybot normally replies with the full help
|
||||
registry.Boolean(False, _("""Supybot normally replies with the full help
|
||||
whenever a user misuses a command. If this value is set to True, the bot
|
||||
will only reply with the syntax of the command (the first line of the
|
||||
help) rather than the full help."""))
|
||||
help) rather than the full help.""")))
|
||||
|
||||
class ValidPrefixChars(registry.String):
|
||||
"""Value must contain only ~!@#$%^&*()_-+=[{}]\\|'\";:,<.>/?"""
|
||||
@ -435,32 +440,32 @@ class ValidPrefixChars(registry.String):
|
||||
|
||||
registerGroup(supybot.reply, 'whenAddressedBy')
|
||||
registerChannelValue(supybot.reply.whenAddressedBy, 'chars',
|
||||
ValidPrefixChars('', """Determines what prefix characters the bot will
|
||||
ValidPrefixChars('', _("""Determines what prefix characters the bot will
|
||||
reply to. A prefix character is a single character that the bot will use
|
||||
to determine what messages are addressed to it; when there are no prefix
|
||||
characters set, it just uses its nick. Each character in this string is
|
||||
interpreted individually; you can have multiple prefix chars
|
||||
simultaneously, and if any one of them is used as a prefix the bot will
|
||||
assume it is being addressed."""))
|
||||
assume it is being addressed.""")))
|
||||
|
||||
registerChannelValue(supybot.reply.whenAddressedBy, 'strings',
|
||||
registry.SpaceSeparatedSetOfStrings([], """Determines what strings the bot
|
||||
will reply to when they are at the beginning of the message. Whereas
|
||||
registry.SpaceSeparatedSetOfStrings([], _("""Determines what strings the
|
||||
bot will reply to when they are at the beginning of the message. Whereas
|
||||
prefix.chars can only be one character (although there can be many of
|
||||
them), this variable is a space-separated list of strings, so you can
|
||||
set something like '@@ ??' and the bot will reply when a message is
|
||||
prefixed by either @@ or ??."""))
|
||||
prefixed by either @@ or ??.""")))
|
||||
registerChannelValue(supybot.reply.whenAddressedBy, 'nick',
|
||||
registry.Boolean(True, """Determines whether the bot will reply when people
|
||||
address it by its nick, rather than with a prefix character."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will reply when
|
||||
people address it by its nick, rather than with a prefix character.""")))
|
||||
registerChannelValue(supybot.reply.whenAddressedBy.nick, 'atEnd',
|
||||
registry.Boolean(False, """Determines whether the bot will reply when
|
||||
registry.Boolean(False, _("""Determines whether the bot will reply when
|
||||
people address it by its nick at the end of the message, rather than at
|
||||
the beginning."""))
|
||||
the beginning.""")))
|
||||
registerChannelValue(supybot.reply.whenAddressedBy, 'nicks',
|
||||
registry.SpaceSeparatedSetOfStrings([], """Determines what extra nicks the
|
||||
bot will always respond to when addressed by, even if its current nick is
|
||||
something else."""))
|
||||
registry.SpaceSeparatedSetOfStrings([], _("""Determines what extra nicks
|
||||
the bot will always respond to when addressed by, even if its current nick
|
||||
is something else.""")))
|
||||
|
||||
###
|
||||
# Replies
|
||||
@ -468,93 +473,96 @@ registerChannelValue(supybot.reply.whenAddressedBy, 'nicks',
|
||||
registerGroup(supybot, 'replies')
|
||||
|
||||
registerChannelValue(supybot.replies, 'success',
|
||||
registry.NormalizedString("""The operation succeeded.""", """Determines
|
||||
what message the bot replies with when a command succeeded. If this
|
||||
configuration variable is empty, no success message will be sent."""))
|
||||
registry.NormalizedString(_("""The operation succeeded."""),
|
||||
_("""Determines what message the bot replies with when a command succeeded.
|
||||
If this configuration variable is empty, no success message will be
|
||||
sent.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, 'error',
|
||||
registry.NormalizedString("""An error has occurred and has been logged.
|
||||
Please contact this bot's administrator for more information.""", """
|
||||
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."""))
|
||||
ambiguous.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, 'incorrectAuthentication',
|
||||
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."""))
|
||||
registry.NormalizedString(_("""Your hostmask doesn't match or your password
|
||||
is wrong."""), _("""Determines what message the bot replies with when
|
||||
someonetries to use a command that requires being identified or having a
|
||||
password and neither credential is correct.""")))
|
||||
|
||||
# XXX: This should eventually check that there's one and only one %s here.
|
||||
registerChannelValue(supybot.replies, 'noUser',
|
||||
registry.NormalizedString("""I can't find %s in my user
|
||||
registry.NormalizedString(_("""I can't find %s in my user
|
||||
database. If you didn't give a user name, then I might not know what your
|
||||
user is, and you'll need to identify before this command might work.""",
|
||||
"""Determines what error message the bot replies with when someone tries
|
||||
to accessing some information on a user the bot doesn't know about."""))
|
||||
user is, and you'll need to identify before this command might work."""),
|
||||
_("""Determines what error message the bot replies with when someone tries
|
||||
to accessing some information on a user the bot doesn't know about.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, 'notRegistered',
|
||||
registry.NormalizedString("""You must be registered to use this command.
|
||||
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
|
||||
"hostmask add" command).""", """Determines what error message the bot
|
||||
"hostmask add" 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."""))
|
||||
registered but they're not currently recognized.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, 'noCapability',
|
||||
registry.NormalizedString("""You don't have the %s capability. If you
|
||||
registry.NormalizedString(_("""You don't have the %s 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."""))
|
||||
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.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, 'genericNoCapability',
|
||||
registry.NormalizedString("""You're missing some capability you need.
|
||||
registry.NormalizedString(_("""You're missing some capability you need.
|
||||
This could be because you actually possess the anti-capability for the
|
||||
capability that's required of you, or because the channel provides that
|
||||
anti-capability by default, or because the global capabilities include
|
||||
that anti-capability. Or, it could be because the channel or
|
||||
supybot.capabilities.default is set to False, meaning that no commands are
|
||||
allowed unless explicitly in your capabilities. Either way, you can't do
|
||||
what you want to do.""",
|
||||
"""Determines what generic error message is given when the bot is telling
|
||||
what you want to do."""),
|
||||
_("""Determines what generic error message is given when the bot is telling
|
||||
someone that they aren't cool enough to use the command they tried to use,
|
||||
and the author of the code calling errorNoCapability didn't provide an
|
||||
explicit capability for whatever reason."""))
|
||||
explicit capability for whatever reason.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, '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."""))
|
||||
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.""")))
|
||||
|
||||
registerChannelValue(supybot.replies, '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>.""",
|
||||
"""Determines what message the bot sends when it thinks you've encountered
|
||||
a bug that the developers don't know about."""))
|
||||
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>."""),
|
||||
_("""Determines what message the bot sends when it thinks you've
|
||||
encountered a bug that the developers don't know about.""")))
|
||||
###
|
||||
# End supybot.replies.
|
||||
###
|
||||
|
||||
registerGlobalValue(supybot, 'snarfThrottle',
|
||||
registry.Float(10.0, """A floating point number of seconds to throttle
|
||||
registry.Float(10.0, _("""A floating point number of seconds to throttle
|
||||
snarfed URLs, in order to prevent loops between two bots snarfing the same
|
||||
URLs and having the snarfed URL in the output of the snarf message."""))
|
||||
URLs and having the snarfed URL in the output of the snarf message.""")))
|
||||
|
||||
registerGlobalValue(supybot, 'upkeepInterval',
|
||||
registry.PositiveInteger(3600, """Determines the number of seconds between
|
||||
running the upkeep function that flushes (commits) open databases, collects
|
||||
garbage, and records some useful statistics at the debugging level."""))
|
||||
registry.PositiveInteger(3600, _("""Determines the number of seconds
|
||||
between running the upkeep function that flushes (commits) open databases,
|
||||
collects garbage, and records some useful statistics at the debugging
|
||||
level.""")))
|
||||
|
||||
registerGlobalValue(supybot, 'flush',
|
||||
registry.Boolean(True, """Determines whether the bot will periodically
|
||||
registry.Boolean(True, _("""Determines whether the bot will periodically
|
||||
flush data and configuration files to disk. Generally, the only time
|
||||
you'll want to set this to False is when you want to modify those
|
||||
configuration files by hand and don't want the bot to flush its current
|
||||
version 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 edit the registry yourself."""))
|
||||
permanent, you must edit the registry yourself.""")))
|
||||
|
||||
|
||||
###
|
||||
@ -573,34 +581,34 @@ class ValidQuotes(registry.Value):
|
||||
return str(self.value)
|
||||
|
||||
registerChannelValue(supybot.commands, 'quotes',
|
||||
ValidQuotes('"', """Determines what characters are valid for quoting
|
||||
ValidQuotes('"', _("""Determines what characters are valid for quoting
|
||||
arguments to commands in order to prevent them from being tokenized.
|
||||
"""))
|
||||
""")))
|
||||
# This is a GlobalValue because bot owners should be able to say, "There will
|
||||
# be no nesting at all on this bot." Individual channels can just set their
|
||||
# brackets to the empty string.
|
||||
registerGlobalValue(supybot.commands, 'nested',
|
||||
registry.Boolean(True, """Determines whether the bot will allow nested
|
||||
commands, which rule. You definitely should keep this on."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will allow nested
|
||||
commands, which rule. You definitely should keep this on.""")))
|
||||
registerGlobalValue(supybot.commands.nested, 'maximum',
|
||||
registry.PositiveInteger(10, """Determines what the maximum number of
|
||||
registry.PositiveInteger(10, _("""Determines what the maximum number of
|
||||
nested commands will be; users will receive an error if they attempt
|
||||
commands more nested than this."""))
|
||||
commands more nested than this.""")))
|
||||
|
||||
class ValidBrackets(registry.OnlySomeStrings):
|
||||
validStrings = ('', '[]', '<>', '{}', '()')
|
||||
|
||||
registerChannelValue(supybot.commands.nested, 'brackets',
|
||||
ValidBrackets('[]', """Supybot allows you to specify what brackets are used
|
||||
for your nested commands. Valid sets of brackets include [], <>, and {}
|
||||
(). [] has strong historical motivation, as well as being the brackets
|
||||
ValidBrackets('[]', _("""Supybot allows you to specify what brackets are
|
||||
used for your nested commands. Valid sets of brackets include [], <>, and
|
||||
{} (). [] has strong historical motivation, as well as being the brackets
|
||||
that don't require shift. <> or () might be slightly superior because they
|
||||
cannot occur in a nick. If this string is empty, nested commands will
|
||||
not be allowed in this channel."""))
|
||||
not be allowed in this channel.""")))
|
||||
registerChannelValue(supybot.commands.nested, 'pipeSyntax',
|
||||
registry.Boolean(False, """Supybot allows nested commands. Enabling this
|
||||
registry.Boolean(False, _("""Supybot allows nested commands. Enabling this
|
||||
option will allow nested commands with a syntax similar to UNIX pipes, for
|
||||
example: 'bot: foo | bar'."""))
|
||||
example: 'bot: foo | bar'.""")))
|
||||
|
||||
registerGroup(supybot.commands, 'defaultPlugins',
|
||||
orderAlphabetically=True, help="""Determines what commands have default
|
||||
@ -609,11 +617,12 @@ registerGroup(supybot.commands, 'defaultPlugins',
|
||||
registerGlobalValue(supybot.commands.defaultPlugins, 'importantPlugins',
|
||||
registry.SpaceSeparatedSetOfStrings(
|
||||
['Admin', 'Channel', 'Config', 'Misc', 'Owner', 'Plugin', 'User'],
|
||||
"""Determines what plugins automatically get precedence over all other
|
||||
plugins when selecting a default plugin for a command. By default,
|
||||
this includes the standard loaded plugins. You probably shouldn't
|
||||
change this if you don't know what you're doing; if you do know what
|
||||
you're doing, then also know that this set is case-sensitive."""))
|
||||
_("""Determines what plugins automatically get precedence over all
|
||||
other plugins when selecting a default plugin for a command. By
|
||||
default, this includes the standard loaded plugins. You probably
|
||||
shouldn't change this if you don't know what you're doing; if you do
|
||||
know what you're doing, then also know that this set is
|
||||
case-sensitive.""")))
|
||||
|
||||
# supybot.commands.disabled moved to callbacks for canonicalName.
|
||||
|
||||
@ -623,37 +632,37 @@ registerGlobalValue(supybot.commands.defaultPlugins, 'importantPlugins',
|
||||
registerGroup(supybot, 'abuse')
|
||||
registerGroup(supybot.abuse, 'flood')
|
||||
registerGlobalValue(supybot.abuse.flood, 'command',
|
||||
registry.Boolean(True, """Determines whether the bot will defend itself
|
||||
against command-flooding."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will defend itself
|
||||
against command-flooding.""")))
|
||||
registerGlobalValue(supybot.abuse.flood.command, 'maximum',
|
||||
registry.PositiveInteger(12, """Determines how many commands users are
|
||||
registry.PositiveInteger(12, _("""Determines how many commands users are
|
||||
allowed per minute. If a user sends more than this many commands in any
|
||||
60 second period, he or she will be ignored for
|
||||
supybot.abuse.flood.command.punishment seconds."""))
|
||||
supybot.abuse.flood.command.punishment seconds.""")))
|
||||
registerGlobalValue(supybot.abuse.flood.command, 'punishment',
|
||||
registry.PositiveInteger(300, """Determines how many seconds the bot
|
||||
will ignore users who flood it with commands."""))
|
||||
registry.PositiveInteger(300, _("""Determines how many seconds the bot
|
||||
will ignore users who flood it with commands.""")))
|
||||
|
||||
registerGlobalValue(supybot.abuse.flood.command, 'invalid',
|
||||
registry.Boolean(True, """Determines whether the bot will defend itself
|
||||
against invalid command-flooding."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will defend itself
|
||||
against invalid command-flooding.""")))
|
||||
registerGlobalValue(supybot.abuse.flood.command.invalid, 'maximum',
|
||||
registry.PositiveInteger(5, """Determines how many invalid commands users
|
||||
registry.PositiveInteger(5, _("""Determines how many invalid commands users
|
||||
are allowed per minute. If a user sends more than this many invalid
|
||||
commands in any 60 second period, he or she will be ignored for
|
||||
supybot.abuse.flood.command.invalid.punishment seconds. Typically, this
|
||||
value is lower than supybot.abuse.flood.command.maximum, since it's far
|
||||
less likely (and far more annoying) for users to flood with invalid
|
||||
commands than for them to flood with valid commands."""))
|
||||
commands than for them to flood with valid commands.""")))
|
||||
registerGlobalValue(supybot.abuse.flood.command.invalid, 'punishment',
|
||||
registry.PositiveInteger(600, """Determines how many seconds the bot
|
||||
registry.PositiveInteger(600, _("""Determines how many seconds the bot
|
||||
will ignore users who flood it with invalid commands. Typically, this
|
||||
value is higher than supybot.abuse.flood.command.punishment, since it's far
|
||||
less likely (and far more annoying) for users to flood witih invalid
|
||||
commands than for them to flood with valid commands."""))
|
||||
commands than for them to flood with valid commands.""")))
|
||||
registerGlobalValue(supybot.abuse.flood.command.invalid, 'notify',
|
||||
registry.Boolean(True, """Determines whether the bot will notify people that they're
|
||||
being ignored for invalid command flooding."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will notify people
|
||||
that they're being ignored for invalid command flooding.""")))
|
||||
|
||||
|
||||
###
|
||||
@ -661,22 +670,22 @@ registerGlobalValue(supybot.abuse.flood.command.invalid, 'notify',
|
||||
###
|
||||
registerGroup(supybot, 'drivers')
|
||||
registerGlobalValue(supybot.drivers, 'poll',
|
||||
registry.PositiveFloat(1.0, """Determines the default length of time a
|
||||
driver should block waiting for input."""))
|
||||
registry.PositiveFloat(1.0, _("""Determines the default length of time a
|
||||
driver should block waiting for input.""")))
|
||||
|
||||
class ValidDriverModule(registry.OnlySomeStrings):
|
||||
validStrings = ('default', 'Socket', 'Twisted')
|
||||
|
||||
registerGlobalValue(supybot.drivers, 'module',
|
||||
ValidDriverModule('default', """Determines what driver module the bot will
|
||||
use. Socket, a simple driver based on timeout sockets, is used by default
|
||||
because it's simple and stable. Twisted is very stable and simple, and if
|
||||
you've got Twisted installed, is probably your best bet."""))
|
||||
ValidDriverModule('default', _("""Determines what driver module the bot
|
||||
will use. Socket, a simple driver based on timeout sockets, is used by
|
||||
default because it's simple and stable. Twisted is very stable and simple,
|
||||
and if you've got Twisted installed, is probably your best bet.""")))
|
||||
|
||||
registerGlobalValue(supybot.drivers, 'maxReconnectWait',
|
||||
registry.PositiveFloat(300.0, """Determines the maximum time the bot will
|
||||
registry.PositiveFloat(300.0, _("""Determines the maximum time the bot will
|
||||
wait before attempting to reconnect to an IRC server. The bot may, of
|
||||
course, reconnect earlier if possible."""))
|
||||
course, reconnect earlier if possible.""")))
|
||||
|
||||
###
|
||||
# supybot.directories, for stuff relating to directories.
|
||||
@ -723,37 +732,38 @@ class DataFilenameDirectory(DataFilename, Directory):
|
||||
|
||||
registerGroup(supybot, 'directories')
|
||||
registerGlobalValue(supybot.directories, 'conf',
|
||||
Directory('conf', """Determines what directory configuration data is
|
||||
put into."""))
|
||||
Directory('conf', _("""Determines what directory configuration data is
|
||||
put into.""")))
|
||||
registerGlobalValue(supybot.directories, 'data',
|
||||
Directory('data', """Determines what directory data is put into."""))
|
||||
Directory('data', _("""Determines what directory data is put into.""")))
|
||||
registerGlobalValue(supybot.directories, 'backup',
|
||||
Directory('backup', """Determines what directory backup data is put
|
||||
into."""))
|
||||
Directory('backup', _("""Determines what directory backup data is put
|
||||
into.""")))
|
||||
registerGlobalValue(supybot.directories.data, 'tmp',
|
||||
DataFilenameDirectory('tmp', """Determines what directory temporary files
|
||||
are put into."""))
|
||||
DataFilenameDirectory('tmp', _("""Determines what directory temporary files
|
||||
are put into.""")))
|
||||
|
||||
utils.file.AtomicFile.default.tmpDir = supybot.directories.data.tmp
|
||||
utils.file.AtomicFile.default.backupDir = supybot.directories.backup
|
||||
|
||||
registerGlobalValue(supybot.directories, 'plugins',
|
||||
registry.CommaSeparatedListOfStrings([], """Determines what directories the
|
||||
bot will look for plugins in. Accepts a comma-separated list of strings.
|
||||
registry.CommaSeparatedListOfStrings([], _("""Determines what directories
|
||||
the bot will look for plugins in. Accepts a comma-separated list of
|
||||
strings.
|
||||
This means that to add another directory, you can nest the former value and
|
||||
add a new one. E.g. you can say: bot: 'config supybot.directories.plugins
|
||||
[config supybot.directories.plugins], newPluginDirectory'."""))
|
||||
[config supybot.directories.plugins], newPluginDirectory'.""")))
|
||||
|
||||
registerGlobalValue(supybot, 'plugins',
|
||||
registry.SpaceSeparatedSetOfStrings([], """Determines what plugins will
|
||||
be loaded.""", orderAlphabetically=True))
|
||||
registry.SpaceSeparatedSetOfStrings([], _("""Determines what plugins will
|
||||
be loaded."""), orderAlphabetically=True))
|
||||
registerGlobalValue(supybot.plugins, 'alwaysLoadImportant',
|
||||
registry.Boolean(True, """Determines whether the bot will always load
|
||||
registry.Boolean(True, _("""Determines whether the bot will always load
|
||||
important plugins (Admin, Channel, Config, Misc, Owner, and User)
|
||||
regardless of what their configured state is. Generally, if these plugins
|
||||
are configured not to load, you didn't do it on purpose, and you still
|
||||
want them to load. Users who don't want to load these plugins are smart
|
||||
enough to change the value of this variable appropriately :)"""))
|
||||
enough to change the value of this variable appropriately :)""")))
|
||||
|
||||
###
|
||||
# supybot.databases. For stuff relating to Supybot's databases (duh!)
|
||||
@ -771,38 +781,38 @@ class Databases(registry.SpaceSeparatedListOfStrings):
|
||||
return ' '.join(self.value)
|
||||
|
||||
registerGlobalValue(supybot, 'databases',
|
||||
Databases([], """Determines what databases are available for use. If this
|
||||
Databases([], _("""Determines what databases are available for use. If this
|
||||
value is not configured (that is, if its value is empty) then sane defaults
|
||||
will be provided."""))
|
||||
will be provided.""")))
|
||||
|
||||
registerGroup(supybot.databases, 'users')
|
||||
registerGlobalValue(supybot.databases.users, 'filename',
|
||||
registry.String('users.conf', """Determines what filename will be used for
|
||||
the users database. This file will go into the directory specified by the
|
||||
supybot.directories.conf variable."""))
|
||||
registry.String('users.conf', _("""Determines what filename will be used
|
||||
for the users database. This file will go into the directory specified by
|
||||
the supybot.directories.conf variable.""")))
|
||||
registerGlobalValue(supybot.databases.users, 'timeoutIdentification',
|
||||
registry.Integer(0, """Determines how long it takes identification to time
|
||||
out. If the value is less than or equal to zero, identification never
|
||||
times out."""))
|
||||
registry.Integer(0, _("""Determines how long it takes identification to
|
||||
time out. If the value is less than or equal to zero, identification never
|
||||
times out.""")))
|
||||
registerGlobalValue(supybot.databases.users, 'allowUnregistration',
|
||||
registry.Boolean(False, """Determines whether the bot will allow users to
|
||||
registry.Boolean(False, _("""Determines whether the bot will allow users to
|
||||
unregister their users. This can wreak havoc with already-existing
|
||||
databases, so by default we don't allow it. Enable this at your own risk.
|
||||
(Do also note that this does not prevent the owner of the bot from using
|
||||
the unregister command.)
|
||||
"""))
|
||||
""")))
|
||||
|
||||
registerGroup(supybot.databases, 'ignores')
|
||||
registerGlobalValue(supybot.databases.ignores, 'filename',
|
||||
registry.String('ignores.conf', """Determines what filename will be used
|
||||
registry.String('ignores.conf', _("""Determines what filename will be used
|
||||
for the ignores database. This file will go into the directory specified
|
||||
by the supybot.directories.conf variable."""))
|
||||
by the supybot.directories.conf variable.""")))
|
||||
|
||||
registerGroup(supybot.databases, 'channels')
|
||||
registerGlobalValue(supybot.databases.channels, 'filename',
|
||||
registry.String('channels.conf', """Determines what filename will be used
|
||||
registry.String('channels.conf', _("""Determines what filename will be used
|
||||
for the channels database. This file will go into the directory specified
|
||||
by the supybot.directories.conf variable."""))
|
||||
by the supybot.directories.conf variable.""")))
|
||||
|
||||
# TODO This will need to do more in the future (such as making sure link.allow
|
||||
# will let the link occur), but for now let's just leave it as this.
|
||||
@ -830,28 +840,28 @@ class ChannelSpecific(registry.Boolean):
|
||||
|
||||
registerGroup(supybot.databases, 'plugins')
|
||||
registerChannelValue(supybot.databases.plugins, 'channelSpecific',
|
||||
ChannelSpecific(True, """Determines whether database-based plugins that
|
||||
ChannelSpecific(True, _("""Determines whether database-based plugins that
|
||||
can be channel-specific will be so. This can be overridden by individual
|
||||
channels. Do note that the bot needs to be restarted immediately after
|
||||
changing this variable or your db plugins may not work for your channel;
|
||||
also note that you may wish to set
|
||||
supybot.databases.plugins.channelSpecific.link appropriately if you wish
|
||||
to share a certain channel's databases globally."""))
|
||||
to share a certain channel's databases globally.""")))
|
||||
registerChannelValue(supybot.databases.plugins.channelSpecific, 'link',
|
||||
ValidChannel('#', """Determines what channel global (non-channel-specific)
|
||||
databases will be considered a part of. This is helpful if you've been
|
||||
running channel-specific for awhile and want to turn the databases for
|
||||
your primary channel into global databases. If
|
||||
ValidChannel('#', _("""Determines what channel global
|
||||
(non-channel-specific) databases will be considered a part of. This is
|
||||
helpful if you've been running channel-specific for awhile and want to turn
|
||||
the databases for your primary channel into global databases. If
|
||||
supybot.databases.plugins.channelSpecific.link.allow prevents linking, the
|
||||
current channel will be used. Do note that the bot needs to be restarted
|
||||
immediately after changing this variable or your db plugins may not work
|
||||
for your channel."""))
|
||||
for your channel.""")))
|
||||
registerChannelValue(supybot.databases.plugins.channelSpecific.link, 'allow',
|
||||
registry.Boolean(True, """Determines whether another channel's global
|
||||
registry.Boolean(True, _("""Determines whether another channel's global
|
||||
(non-channel-specific) databases will be allowed to link to this channel's
|
||||
databases. Do note that the bot needs to be restarted immediately after
|
||||
changing this variable or your db plugins may not work for your channel.
|
||||
"""))
|
||||
""")))
|
||||
|
||||
|
||||
class CDB(registry.Boolean):
|
||||
@ -864,13 +874,13 @@ class CDB(registry.Boolean):
|
||||
maxmods=self.maximumModifications())
|
||||
|
||||
registerGroup(supybot.databases, 'types')
|
||||
registerGlobalValue(supybot.databases.types, 'cdb', CDB(True, """Determines
|
||||
whether CDB databases will be allowed as a database implementation."""))
|
||||
registerGlobalValue(supybot.databases.types, 'cdb', CDB(True, _("""Determines
|
||||
whether CDB databases will be allowed as a database implementation.""")))
|
||||
registerGlobalValue(supybot.databases.types.cdb, 'maximumModifications',
|
||||
registry.Probability(0.5, """Determines how often CDB databases will have
|
||||
registry.Probability(0.5, _("""Determines how often CDB databases will have
|
||||
their modifications flushed to disk. When the number of modified records
|
||||
is greater than this fraction of the total number of records, the database
|
||||
will be entirely flushed to disk."""))
|
||||
will be entirely flushed to disk.""")))
|
||||
|
||||
# XXX Configuration variables for dbi, sqlite, flat, mysql, etc.
|
||||
|
||||
@ -952,73 +962,73 @@ class Banmask(registry.SpaceSeparatedSetOfStrings):
|
||||
return ircutils.joinHostmask(bnick, buser, bhost)
|
||||
|
||||
registerChannelValue(supybot.protocols.irc, 'banmask',
|
||||
Banmask(['user', 'host'], """Determines what will be used as the
|
||||
default banmask style."""))
|
||||
Banmask(['user', 'host'], _("""Determines what will be used as the
|
||||
default banmask style.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'strictRfc',
|
||||
registry.Boolean(True, """Determines whether the bot will strictly follow
|
||||
registry.Boolean(True, _("""Determines whether the bot will strictly follow
|
||||
the RFC; currently this only affects what strings are considered to be
|
||||
nicks. If you're using a server or a network that requires you to message
|
||||
a nick such as services@this.network.server then you you should set this to
|
||||
False."""))
|
||||
False.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'umodes',
|
||||
registry.String('', """Determines what user modes the bot will request from
|
||||
the server when it first connects. Many people might choose +i; some
|
||||
registry.String('', _("""Determines what user modes the bot will request
|
||||
from the server when it first connects. Many people might choose +i; some
|
||||
networks allow +x, which indicates to the auth services on those networks
|
||||
that you should be given a fake host."""))
|
||||
that you should be given a fake host.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'vhost',
|
||||
registry.String('', """Determines what vhost the bot will bind to before
|
||||
connecting to the IRC server."""))
|
||||
registry.String('', _("""Determines what vhost the bot will bind to before
|
||||
connecting to the IRC server.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'maxHistoryLength',
|
||||
registry.Integer(1000, """Determines how many old messages the bot will
|
||||
registry.Integer(1000, _("""Determines how many old messages the bot will
|
||||
keep around in its history. Changing this variable will not take effect
|
||||
until the bot is restarted."""))
|
||||
until the bot is restarted.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'throttleTime',
|
||||
registry.Float(1.0, """A floating point number of seconds to throttle
|
||||
registry.Float(1.0, _("""A floating point number of seconds to throttle
|
||||
queued messages -- that is, messages will not be sent faster than once per
|
||||
throttleTime seconds."""))
|
||||
throttleTime seconds.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc, 'ping',
|
||||
registry.Boolean(True, """Determines whether the bot will send PINGs to the
|
||||
server it's connected to in order to keep the connection alive and discover
|
||||
earlier when it breaks. Really, this option only exists for debugging
|
||||
purposes: you always should make it True unless you're testing some strange
|
||||
server issues."""))
|
||||
registry.Boolean(True, _("""Determines whether the bot will send PINGs to
|
||||
the server it's connected to in order to keep the connection alive and
|
||||
discover earlier when it breaks. Really, this option only exists for
|
||||
debugging purposes: you always should make it True unless you're testing
|
||||
some strange server issues.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.irc.ping, 'interval',
|
||||
registry.Integer(120, """Determines the number of seconds between sending
|
||||
pings to the server, if pings are being sent to the server."""))
|
||||
registry.Integer(120, _("""Determines the number of seconds between sending
|
||||
pings to the server, if pings are being sent to the server.""")))
|
||||
|
||||
registerGroup(supybot.protocols.irc, 'queuing')
|
||||
registerGlobalValue(supybot.protocols.irc.queuing, 'duplicates',
|
||||
registry.Boolean(False, """Determines whether the bot will refuse duplicate
|
||||
messages to be queued for delivery to the server. This is a safety
|
||||
mechanism put in place to prevent plugins from sending the same message
|
||||
multiple times; most of the time it doesn't matter, unless you're doing
|
||||
certain kinds of plugin hacking."""))
|
||||
registry.Boolean(False, _("""Determines whether the bot will refuse
|
||||
duplicate messages to be queued for delivery to the server. This is a
|
||||
safety mechanism put in place to prevent plugins from sending the same
|
||||
message multiple times; most of the time it doesn't matter, unless you're
|
||||
doing certain kinds of plugin hacking.""")))
|
||||
|
||||
registerGroup(supybot.protocols.irc.queuing, 'rateLimit')
|
||||
registerGlobalValue(supybot.protocols.irc.queuing.rateLimit, 'join',
|
||||
registry.Float(0, """Determines how many seconds must elapse between JOINs
|
||||
sent to the server."""))
|
||||
registry.Float(0, _("""Determines how many seconds must elapse between
|
||||
JOINs sent to the server.""")))
|
||||
|
||||
###
|
||||
# supybot.protocols.http
|
||||
###
|
||||
registerGroup(supybot.protocols, 'http')
|
||||
registerGlobalValue(supybot.protocols.http, 'peekSize',
|
||||
registry.PositiveInteger(4096, """Determines how many bytes the bot will
|
||||
registry.PositiveInteger(4096, _("""Determines how many bytes the bot will
|
||||
'peek' at when looking through a URL for a doctype or title or something
|
||||
similar. It'll give up after it reads this many bytes, even if it hasn't
|
||||
found what it was looking for."""))
|
||||
found what it was looking for.""")))
|
||||
|
||||
registerGlobalValue(supybot.protocols.http, 'proxy',
|
||||
registry.String('', """Determines what proxy all HTTP requests should go
|
||||
through. The value should be of the form 'host:port'."""))
|
||||
registry.String('', _("""Determines what proxy all HTTP requests should go
|
||||
through. The value should be of the form 'host:port'.""")))
|
||||
utils.web.proxy = supybot.protocols.http.proxy
|
||||
|
||||
|
||||
@ -1026,10 +1036,10 @@ utils.web.proxy = supybot.protocols.http.proxy
|
||||
# Especially boring stuff.
|
||||
###
|
||||
registerGlobalValue(supybot, 'defaultIgnore',
|
||||
registry.Boolean(False, """Determines whether the bot will ignore
|
||||
registry.Boolean(False, _("""Determines whether the bot will ignore
|
||||
unregistered users by default. Of course, that'll make it particularly
|
||||
hard for those users to register or identify with the bot, but that's your
|
||||
problem to solve."""))
|
||||
problem to solve.""")))
|
||||
|
||||
class IP(registry.String):
|
||||
"""Value must be a valid IP."""
|
||||
@ -1040,9 +1050,9 @@ class IP(registry.String):
|
||||
registry.String.setValue(self, v)
|
||||
|
||||
registerGlobalValue(supybot, '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 dynamically (though
|
||||
sometimes that doesn't work, hence this variable)."""))
|
||||
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 dynamically (though
|
||||
sometimes that doesn't work, hence this variable).""")))
|
||||
|
||||
class SocketTimeout(registry.PositiveInteger):
|
||||
"""Value must be an integer greater than supybot.drivers.poll and must be
|
||||
@ -1054,28 +1064,28 @@ class SocketTimeout(registry.PositiveInteger):
|
||||
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)."""))
|
||||
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
|
||||
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."""))
|
||||
changes to this variable to take effect.""")))
|
||||
|
||||
###
|
||||
# Debugging options.
|
||||
###
|
||||
registerGroup(supybot, 'debug')
|
||||
registerGlobalValue(supybot.debug, 'threadAllCommands',
|
||||
registry.Boolean(False, """Determines whether the bot will automatically
|
||||
thread all commands."""))
|
||||
registry.Boolean(False, _("""Determines whether the bot will automatically
|
||||
thread all commands.""")))
|
||||
registerGlobalValue(supybot.debug, 'flushVeryOften',
|
||||
registry.Boolean(False, """Determines whether the bot will automatically
|
||||
registry.Boolean(False, _("""Determines whether the bot will automatically
|
||||
flush all flushers *very* often. Useful for debugging when you don't know
|
||||
what's breaking or when, but think that it might be logged."""))
|
||||
what's breaking or when, but think that it might be logged.""")))
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
Loading…
Reference in New Issue
Block a user