2003-03-12 07:26:59 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
###
|
|
|
|
# Copyright (c) 2002, Jeremiah Fincher
|
|
|
|
# All rights reserved.
|
|
|
|
#
|
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
# modification, are permitted provided that the following conditions are met:
|
|
|
|
#
|
|
|
|
# * Redistributions of source code must retain the above copyright notice,
|
|
|
|
# this list of conditions, and the following disclaimer.
|
|
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
# this list of conditions, and the following disclaimer in the
|
|
|
|
# documentation and/or other materials provided with the distribution.
|
|
|
|
# * Neither the name of the author of this software nor the name of
|
|
|
|
# contributors to this software may be used to endorse or promote products
|
|
|
|
# derived from this software without specific prior written consent.
|
|
|
|
#
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
###
|
|
|
|
|
2003-11-25 09:38:19 +01:00
|
|
|
__revision__ = "$Id$"
|
|
|
|
|
2003-10-05 14:47:19 +02:00
|
|
|
import fix
|
2003-03-12 07:26:59 +01:00
|
|
|
|
2003-12-01 16:38:42 +01:00
|
|
|
import os
|
2003-09-24 09:28:25 +02:00
|
|
|
import sys
|
2004-02-07 12:12:12 +01:00
|
|
|
import socket
|
2004-01-18 08:58:26 +01:00
|
|
|
import string
|
2003-09-24 09:28:25 +02:00
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
import utils
|
|
|
|
import registry
|
|
|
|
import ircutils
|
2003-03-12 07:26:59 +01:00
|
|
|
|
2003-09-24 09:28:25 +02:00
|
|
|
installDir = os.path.dirname(os.path.dirname(sys.modules[__name__].__file__))
|
2004-01-18 08:58:26 +01:00
|
|
|
_srcDir = os.path.join(installDir, 'src')
|
|
|
|
_pluginsDir = os.path.join(installDir, 'plugins')
|
2003-11-07 13:47:36 +01:00
|
|
|
|
2004-04-18 07:56:31 +02:00
|
|
|
###
|
|
|
|
# version: This should be pretty obvious.
|
|
|
|
###
|
2004-04-20 23:14:13 +02:00
|
|
|
version ='0.77.2+cvs'
|
2004-04-18 07:56:31 +02:00
|
|
|
|
|
|
|
###
|
|
|
|
# daemonized: This determines whether or not the bot has been daemonized
|
|
|
|
# (i.e., set to run in the background). Obviously, this defaults
|
|
|
|
# to False.
|
|
|
|
###
|
|
|
|
daemonized = False
|
|
|
|
|
2003-03-12 07:26:59 +01:00
|
|
|
###
|
|
|
|
# allowEval: True if the owner (and only the owner) should be able to eval
|
2004-01-18 08:58:26 +01:00
|
|
|
# arbitrary Python code. This is specifically *not* a registry
|
|
|
|
# variable because it shouldn't be modifiable in the bot.
|
2003-03-12 07:26:59 +01:00
|
|
|
###
|
2004-02-04 00:55:31 +01:00
|
|
|
allowEval = False
|
2003-03-12 07:26:59 +01:00
|
|
|
|
2004-04-30 20:24:35 +02:00
|
|
|
###
|
|
|
|
# The standard registry.
|
|
|
|
###
|
2004-01-18 08:58:26 +01:00
|
|
|
supybot = registry.Group()
|
|
|
|
supybot.setName('supybot')
|
|
|
|
|
2004-04-30 20:24:35 +02:00
|
|
|
def registerGroup(Group, name, group=None):
|
|
|
|
Group.register(name, group)
|
|
|
|
|
|
|
|
def registerGlobalValue(group, name, value):
|
|
|
|
group.register(name, value)
|
2004-01-19 23:07:41 +01:00
|
|
|
|
|
|
|
def registerChannelValue(group, name, value):
|
2004-02-03 17:43:22 +01:00
|
|
|
value.supplyDefault = True
|
|
|
|
group.register(name, value)
|
2004-01-19 23:07:41 +01:00
|
|
|
|
2004-04-30 20:24:35 +02:00
|
|
|
def registerPlugin(name, currentValue=None):
|
|
|
|
registerGlobalValue(supybot.plugins, name,
|
|
|
|
registry.Boolean(False, """Determines whether this plugin is loaded by
|
|
|
|
default.""", showDefault=False))
|
|
|
|
if currentValue is not None:
|
|
|
|
supybot.plugins.get(name).setValue(currentValue)
|
|
|
|
registerGroup(users.plugins, name)
|
|
|
|
|
|
|
|
###
|
|
|
|
# The user info registry.
|
|
|
|
###
|
|
|
|
users = registry.Group()
|
|
|
|
users.setName('users')
|
|
|
|
registerGroup(users, 'plugins')
|
|
|
|
|
|
|
|
def registerUserValue(group, name, value):
|
2004-04-30 21:20:47 +02:00
|
|
|
assert group.name.startswith('users')
|
2004-04-30 20:24:35 +02:00
|
|
|
value.supplyDefault = True
|
2004-02-03 17:43:22 +01:00
|
|
|
group.register(name, value)
|
2004-01-20 17:17:56 +01:00
|
|
|
|
2004-01-21 20:13:59 +01:00
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
class ValidNick(registry.String):
|
2004-04-13 03:01:52 +02:00
|
|
|
"""Value must be a valid IRC nick."""
|
2004-01-21 18:13:04 +01:00
|
|
|
def setValue(self, v):
|
|
|
|
if not ircutils.isNick(v):
|
2004-04-13 03:01:52 +02:00
|
|
|
self.error()
|
2004-01-21 18:13:04 +01:00
|
|
|
else:
|
|
|
|
registry.String.setValue(self, v)
|
|
|
|
|
|
|
|
class ValidChannel(registry.String):
|
2004-04-13 03:01:52 +02:00
|
|
|
"""Value must be a valid IRC channel name."""
|
2004-01-21 18:13:04 +01:00
|
|
|
def setValue(self, v):
|
2004-02-10 01:00:27 +01:00
|
|
|
if ',' in v:
|
|
|
|
(channel, _) = v.split(',', 1)
|
|
|
|
else:
|
|
|
|
channel = v
|
|
|
|
if not ircutils.isChannel(channel):
|
2004-04-13 03:01:52 +02:00
|
|
|
self.error()
|
2004-01-21 18:13:04 +01:00
|
|
|
else:
|
|
|
|
registry.String.setValue(self, v)
|
2004-01-18 08:58:26 +01:00
|
|
|
|
|
|
|
supybot.register('nick', ValidNick('supybot',
|
|
|
|
"""Determines the bot's nick."""))
|
|
|
|
|
|
|
|
supybot.register('ident', ValidNick('supybot',
|
|
|
|
"""Determines the bot's ident."""))
|
|
|
|
|
|
|
|
supybot.register('user', registry.String('supybot', """Determines the user
|
|
|
|
the bot sends to the server."""))
|
|
|
|
|
|
|
|
# TODO: Make this check for validity.
|
|
|
|
supybot.register('server', registry.String('irc.freenode.net', """Determines
|
|
|
|
what server the bot connects to."""))
|
|
|
|
|
2004-02-03 17:43:22 +01:00
|
|
|
supybot.register('password', registry.String('', """Determines the password to
|
|
|
|
be sent to the server if it requires one."""))
|
|
|
|
|
2004-02-11 07:27:35 +01:00
|
|
|
class SpaceSeparatedSetOfChannels(registry.SeparatedListOf):
|
|
|
|
List = ircutils.IrcSet
|
2004-01-21 18:13:04 +01:00
|
|
|
Value = ValidChannel
|
|
|
|
def splitter(self, s):
|
|
|
|
return s.split()
|
|
|
|
joiner = ' '.join
|
|
|
|
|
2004-03-25 13:15:57 +01:00
|
|
|
def removeChannel(self, channel):
|
|
|
|
removals = []
|
|
|
|
for c in self.value:
|
|
|
|
chan = c
|
|
|
|
if ',' in c:
|
|
|
|
(chan, _) = c.split(',')
|
|
|
|
if chan == channel:
|
|
|
|
removals.append(c)
|
|
|
|
for removal in removals:
|
|
|
|
self.value.remove(discard)
|
|
|
|
|
2004-02-11 07:27:35 +01:00
|
|
|
supybot.register('channels', SpaceSeparatedSetOfChannels(['#supybot'], """
|
2004-01-21 18:13:04 +01:00
|
|
|
Determines what channels the bot will join when it connects to the server."""))
|
2004-01-18 08:58:26 +01:00
|
|
|
|
2004-02-03 18:40:19 +01:00
|
|
|
class ValidPrefixChars(registry.String):
|
2004-04-13 03:01:52 +02:00
|
|
|
"""Value must contain only ~!@#$%^&*()_-+=[{}]\\|'\";:,<.>/?"""
|
2004-02-03 19:21:19 +01:00
|
|
|
def setValue(self, v):
|
|
|
|
if v.translate(string.ascii, '`~!@#$%^&*()_-+=[{}]\\|\'";:,<.>/?'):
|
2004-04-13 03:01:52 +02:00
|
|
|
self.error()
|
2004-02-03 19:21:19 +01:00
|
|
|
registry.String.setValue(self, v)
|
2004-02-03 18:40:19 +01:00
|
|
|
|
2004-02-03 19:21:19 +01:00
|
|
|
supybot.register('prefixChars', ValidPrefixChars('', """Determines what prefix
|
2004-02-03 18:40:19 +01:00
|
|
|
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
|
2004-02-19 09:04:09 +01:00
|
|
|
there are no prefix characters set, it just uses its nick. Each character in
|
|
|
|
this string is interpreted individually; you can have multiple prefixChars
|
|
|
|
simultaneously, and if any one of them is used as a prefix the bot will
|
|
|
|
assume it is being addressed."""))
|
2004-02-03 18:40:19 +01:00
|
|
|
|
|
|
|
supybot.register('defaultCapabilities',
|
|
|
|
registry.CommaSeparatedSetOfStrings(['-owner', '-admin', '-trusted'], """
|
|
|
|
These are the capabilities that are given to everyone by default. If they are
|
|
|
|
normal capabilities, then the user will have to have the appropriate
|
|
|
|
anti-capability if you want to override these capabilities; if they are
|
|
|
|
anti-capabilities, then the user will have to have the actual capability to
|
|
|
|
override these capabilities. See docs/CAPABILITIES if you don't understand
|
|
|
|
why these default to what they do."""))
|
|
|
|
|
2004-02-03 18:59:45 +01:00
|
|
|
supybot.register('defaultAllow', registry.Boolean(True, """Determines whether
|
|
|
|
the bot by default will allow users to run commands. If this is disabled, a
|
|
|
|
user will have to have the capability for whatever command he wishes to run.
|
|
|
|
"""))
|
|
|
|
|
|
|
|
supybot.register('defaultIgnore', 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 with the bot, but that's
|
|
|
|
your problem to solve."""))
|
2004-02-03 18:40:19 +01:00
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
supybot.register('humanTimestampFormat', 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
|
|
|
|
characteres for time formats."""))
|
|
|
|
|
|
|
|
class IP(registry.String):
|
2004-04-13 03:01:52 +02:00
|
|
|
"""Value must be a valid IP."""
|
2004-01-21 18:13:04 +01:00
|
|
|
def setValue(self, v):
|
|
|
|
if v and not (utils.isIP(v) or utils.isIPV6(v)):
|
2004-04-13 03:01:52 +02:00
|
|
|
self.error()
|
2004-01-21 18:13:04 +01:00
|
|
|
else:
|
|
|
|
registry.String.setValue(self, v)
|
2004-01-18 08:58:26 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
dynamically (though sometimes that doesn't work, hence this variable)."""))
|
|
|
|
|
|
|
|
###
|
|
|
|
# Reply/error tweaking.
|
|
|
|
###
|
2004-02-03 17:43:22 +01:00
|
|
|
supybot.register('reply')
|
2004-04-05 18:01:36 +02:00
|
|
|
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."""))
|
2004-04-05 19:36:17 +02:00
|
|
|
supybot.reply.register('maximumMores', registry.PositiveInteger(50, """
|
|
|
|
Determines what the maximum number of chunks (for use with the 'more' command)
|
|
|
|
will be."""))
|
2004-04-05 18:01:36 +02:00
|
|
|
|
2004-01-19 21:51:04 +01:00
|
|
|
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."""))
|
|
|
|
|
2004-02-18 16:39:30 +01:00
|
|
|
supybot.register('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]'."""))
|
|
|
|
|
2004-03-30 10:27:05 +02:00
|
|
|
class ValidBrackets(registry.OnlySomeStrings):
|
2004-04-22 06:28:54 +02:00
|
|
|
validStrings = ('', '[]', '<>', '{}', '()')
|
2004-03-30 10:27:05 +02:00
|
|
|
|
|
|
|
supybot.register('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."""))
|
|
|
|
|
2004-02-03 18:59:45 +01:00
|
|
|
supybot.register('pipeSyntax', registry.Boolean(False, """Supybot allows
|
2004-02-18 16:39:30 +01:00
|
|
|
nested commands. Enabling this option will allow nested commands with a syntax
|
|
|
|
similar to UNIX pipes, for example: 'bot: foo | bar'."""))
|
2004-02-03 18:59:45 +01:00
|
|
|
|
|
|
|
supybot.reply.register('whenNotCommand', 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."""))
|
|
|
|
|
2004-04-17 18:45:29 +02:00
|
|
|
supybot.reply.register('detailedErrors', registry.Boolean(False, """Determines
|
2004-01-20 23:26:48 +01:00
|
|
|
whether error messages that result from bugs in the bot will show a detailed
|
|
|
|
error message (the uncaught exception) or a generic error message."""))
|
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
supybot.reply.register('errorInPrivate', registry.Boolean(False, """
|
2004-04-09 04:55:03 +02:00
|
|
|
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.errorWithNotice."""))
|
|
|
|
|
|
|
|
supybot.reply.register('errorWithNotice', 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."""))
|
2004-01-18 08:58:26 +01:00
|
|
|
|
2004-01-20 23:39:15 +01:00
|
|
|
supybot.reply.register('noCapabilityError', 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
|
2004-02-16 09:36:29 +01:00
|
|
|
wish to make this True if you don't want users to understand the underlying
|
2004-01-20 23:39:15 +01:00
|
|
|
security system preventing them from running certain commands."""))
|
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
supybot.reply.register('withPrivateNotice', registry.Boolean(False, """
|
|
|
|
Determines whether the bot will reply with a private notice to users rather
|
|
|
|
than sending a message to a channel. Private notices are particularly nice
|
|
|
|
because they don't generally cause IRC clients to open a new query window."""))
|
|
|
|
|
|
|
|
supybot.reply.register('withNickPrefix', registry.Boolean(True, """
|
|
|
|
Determines whether the bot will always prefix the user's nick to its reply to
|
|
|
|
that user's command."""))
|
|
|
|
|
|
|
|
supybot.reply.register('whenAddressedByNick', registry.Boolean(True, """
|
|
|
|
Determines whether the bot will reply when people address it by its nick,
|
|
|
|
rather than with a prefix character."""))
|
|
|
|
|
|
|
|
supybot.reply.register('whenNotAddressed', 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."""))
|
|
|
|
|
|
|
|
supybot.reply.register('requireChannelCommandsToBeSentInChannel',
|
|
|
|
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."""))
|
|
|
|
|
|
|
|
supybot.register('followIdentificationThroughNickChanges',
|
|
|
|
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.
|
|
|
|
"""))
|
|
|
|
|
|
|
|
supybot.register('alwaysJoinOnInvite', 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)"""))
|
|
|
|
|
|
|
|
supybot.register('showSimpleSyntax', 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 docstring) rather than the full help."""))
|
|
|
|
|
|
|
|
###
|
|
|
|
# Replies
|
|
|
|
###
|
2004-02-03 17:43:22 +01:00
|
|
|
supybot.register('replies')
|
2004-01-18 08:58:26 +01:00
|
|
|
|
2004-02-03 18:59:45 +01:00
|
|
|
registerChannelValue(supybot.replies, 'success',
|
|
|
|
registry.NormalizedString("""The operation succeeded.""", """Determines
|
|
|
|
what message the bot replies with when a command succeeded."""))
|
|
|
|
|
2004-01-20 16:55:33 +01:00
|
|
|
registerChannelValue(supybot.replies, 'error',
|
2004-01-19 21:51:04 +01:00
|
|
|
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
|
2004-01-19 23:07:41 +01:00
|
|
|
ambiguous."""))
|
2004-01-19 21:51:04 +01:00
|
|
|
|
2004-01-19 23:07:41 +01:00
|
|
|
registerChannelValue(supybot.replies, 'incorrectAuthentication',
|
2004-01-19 21:51:04 +01:00
|
|
|
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
|
2004-01-19 23:07:41 +01:00
|
|
|
and neither credential is correct."""))
|
2004-01-19 21:51:04 +01:00
|
|
|
|
2004-01-19 23:07:41 +01:00
|
|
|
registerChannelValue(supybot.replies, 'noUser',
|
2004-01-19 21:51:04 +01:00
|
|
|
registry.NormalizedString("""I can't find that user in my user
|
2004-02-13 08:25:24 +01:00
|
|
|
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.""",
|
2004-01-23 15:52:04 +01:00
|
|
|
"""Determines what error message the bot replies with when someone tries
|
|
|
|
to accessing some information on a user the bot doesn't know about."""))
|
2004-01-19 21:51:04 +01:00
|
|
|
|
2004-01-19 23:07:41 +01:00
|
|
|
registerChannelValue(supybot.replies, 'notRegistered',
|
2004-01-19 21:51:04 +01:00
|
|
|
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
|
2004-01-19 23:07:41 +01:00
|
|
|
but they're not currently recognized."""))
|
2004-01-19 21:51:04 +01:00
|
|
|
|
2004-02-03 18:59:45 +01:00
|
|
|
registerChannelValue(supybot.replies, '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."""))
|
|
|
|
|
|
|
|
registerChannelValue(supybot.replies, 'genericNoCapability',
|
|
|
|
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 the global
|
|
|
|
defaultAllow is set to False, meaning that no commands are allowed unless
|
|
|
|
explicitly in your capabilities. Either way, you can't do what you want
|
2004-04-30 04:13:42 +02:00
|
|
|
to do.""", """Determines what generic error message is given when the bot
|
2004-02-03 18:59:45 +01:00
|
|
|
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."""))
|
|
|
|
|
2004-01-19 23:07:41 +01:00
|
|
|
registerChannelValue(supybot.replies, 'requiresPrivacy',
|
2004-01-19 21:51:04 +01:00
|
|
|
registry.NormalizedString("""That operation cannot be done in a
|
|
|
|
channel.""", """Determines what error messages the bot sends to people who
|
2004-01-19 23:07:41 +01:00
|
|
|
try to do things in a channel that really should be done in private."""))
|
2004-01-19 21:51:04 +01:00
|
|
|
|
2004-02-06 09:48:35 +01:00
|
|
|
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."""))
|
2004-01-19 23:07:41 +01:00
|
|
|
###
|
|
|
|
# End supybot.replies.
|
|
|
|
###
|
2004-01-18 08:58:26 +01:00
|
|
|
|
|
|
|
supybot.register('nickmods', registry.CommaSeparatedListOfStrings(
|
|
|
|
'__%s__,%s^,%s`,%s_,%s__,_%s,__%s,[%s]'.split(','),
|
|
|
|
"""A list of modifications to be made to a nick when the nick the bot tries
|
|
|
|
to get from the server is in use. There should be one %s in each string;
|
|
|
|
this will get replaced with the original nick."""))
|
|
|
|
|
2004-02-03 18:59:45 +01:00
|
|
|
supybot.register('snarfThrottle', 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."""))
|
|
|
|
|
2004-02-16 10:13:48 +01:00
|
|
|
supybot.register('upkeepInterval', registry.PositiveInteger(3600, """Determines
|
2004-02-08 11:49:08 +01:00
|
|
|
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."""))
|
|
|
|
|
2004-02-03 23:58:54 +01:00
|
|
|
supybot.register('flush', 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
|
2004-02-04 06:11:31 +01:00
|
|
|
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."""))
|
2004-02-03 23:58:54 +01:00
|
|
|
|
2004-02-07 12:12:12 +01:00
|
|
|
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
|
2004-02-07 12:23:19 +01:00
|
|
|
the author of the code that uses the sockets)."""))
|
2004-02-07 12:12:12 +01:00
|
|
|
|
2004-04-19 07:05:53 +02:00
|
|
|
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."""))
|
|
|
|
|
2004-01-18 08:58:26 +01:00
|
|
|
###
|
2004-04-19 07:05:53 +02:00
|
|
|
# supybot.drivers. For stuff relating to Supybot's drivers (duh!)
|
2004-01-18 08:58:26 +01:00
|
|
|
###
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGroup(supybot, 'drivers')
|
|
|
|
registerGlobalValue(supybot.drivers, 'poll',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.Float(1.0, """Determines the default length of time a driver
|
|
|
|
should block waiting for input."""))
|
2004-01-18 08:58:26 +01:00
|
|
|
|
2004-04-08 12:50:05 +02:00
|
|
|
class ValidDriverModule(registry.OnlySomeStrings):
|
2004-04-30 04:13:42 +02:00
|
|
|
validStrings = ('default', 'socketDrivers',
|
|
|
|
'twistedDrivers', 'asyncoreDrivers')
|
2004-02-03 18:59:45 +01:00
|
|
|
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.drivers, 'module',
|
2004-04-30 20:24:35 +02:00
|
|
|
ValidDriverModule('default', """Determines what driver module the bot will
|
|
|
|
use. socketDrivers, a simple driver based on timeout sockets, is used by
|
|
|
|
default because it's simple and stable. asyncoreDrivers is a bit older
|
|
|
|
(and less well-maintained) but allows you to integrate with asyncore-based
|
|
|
|
applications. twistedDrivers is very stable and simple, and if you've got
|
|
|
|
Twisted installed, is probably your best bet."""))
|
2004-04-19 07:05:53 +02:00
|
|
|
|
|
|
|
###
|
2004-04-30 04:13:42 +02:00
|
|
|
# supybot.directories, for stuff relating to directories.
|
2004-04-19 07:05:53 +02:00
|
|
|
###
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGroup(supybot, 'directories')
|
|
|
|
registerGlobalValue(supybot.directories, 'conf',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.String('conf', """Determines what directory configuration data is
|
|
|
|
put into."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.directories, 'data',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.String('data', """Determines what directory data is put into."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.directories, 'plugins',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.CommaSeparatedListOfStrings([_srcDir,_pluginsDir], """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'."""))
|
2004-02-03 18:59:45 +01:00
|
|
|
|
2004-02-03 17:43:22 +01:00
|
|
|
supybot.register('plugins') # This will be used by plugins, but not here.
|
2004-02-02 18:19:38 +01:00
|
|
|
|
2004-04-30 04:13:42 +02:00
|
|
|
###
|
|
|
|
# supybot.databases. For stuff relating to Supybot's databases (duh!)
|
|
|
|
###
|
|
|
|
registerGroup(supybot, 'databases')
|
|
|
|
registerGroup(supybot.databases, 'users')
|
|
|
|
registerGlobalValue(supybot.databases.users, 'filename',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.databases.users, 'timeoutIdentification',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.databases.users, 'hash',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.Boolean(True, """Determines whether the passwords in the user
|
|
|
|
database will be hashed by default."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
registerGroup(supybot.databases, 'ignores')
|
|
|
|
registerGlobalValue(supybot.databases.ignores, 'filename',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
registerGroup(supybot.databases, 'channels')
|
|
|
|
registerGlobalValue(supybot.databases.channels, 'filename',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
2004-04-29 13:41:05 +02:00
|
|
|
###
|
|
|
|
# Protocol information.
|
|
|
|
###
|
|
|
|
class StrictRfc(registry.Boolean):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.originalIsNick = ircutils.isNick
|
|
|
|
registry.Boolean.__init__(self, *args, **kwargs)
|
|
|
|
|
|
|
|
def setValue(self, v):
|
|
|
|
registry.Boolean.setValue(self, v)
|
|
|
|
# Now let's replace ircutils.isNick.
|
|
|
|
if self.value:
|
|
|
|
ircutils.isNick = self.originalIsNick
|
|
|
|
else:
|
|
|
|
def unstrictIsNick(s):
|
|
|
|
return not ircutils.isChannel(s)
|
|
|
|
ircutils.isNick = unstrictIsNick
|
|
|
|
|
|
|
|
registerGroup(supybot, 'protocols')
|
|
|
|
registerGroup(supybot.protocols, 'irc')
|
|
|
|
registerGlobalValue(supybot.protocols.irc, 'strictRfc',
|
2004-04-30 20:24:35 +02:00
|
|
|
StrictRfc(False, """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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
registerGlobalValue(supybot.protocols.irc, 'maxHistoryLength',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
registerGlobalValue(supybot.protocols.irc, 'throttleTime',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
registerGlobalValue(supybot.protocols.irc, 'ping',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.protocols.irc.ping, 'interval',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.Integer(120, """Determines the number of seconds between sending
|
|
|
|
pings to the server, if pings are being sent to the server."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
registerGroup(supybot.protocols, 'http')
|
|
|
|
registerGlobalValue(supybot.protocols.http, 'peekSize',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
###
|
|
|
|
# Debugging options.
|
|
|
|
###
|
|
|
|
registerGroup(supybot, 'debug')
|
|
|
|
registerGlobalValue(supybot.debug, 'threadAllCommands',
|
2004-04-30 20:24:35 +02:00
|
|
|
registry.Boolean(False, """Determines whether the bot will automatically
|
|
|
|
thread all commands."""))
|
2004-04-30 04:13:42 +02:00
|
|
|
registerGlobalValue(supybot.debug, 'flushVeryOften',
|
2004-04-30 20:24:35 +02:00
|
|
|
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."""))
|
|
|
|
|
|
|
|
# Let's open this now since we've got our directories setup.
|
|
|
|
userdataFilename = os.path.join(supybot.directories.conf(), 'userdata.conf')
|
|
|
|
if not os.path.exists(userdataFilename):
|
|
|
|
fd = file(userdataFilename, 'w')
|
|
|
|
fd.write('\n')
|
|
|
|
fd.close()
|
|
|
|
registry.open(userdataFilename)
|
2004-04-30 04:13:42 +02:00
|
|
|
|
|
|
|
|
2003-08-22 09:20:31 +02:00
|
|
|
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|