mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-11-03 00:57:30 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			673 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			673 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
 | 
						|
import supybot
 | 
						|
 | 
						|
import fix
 | 
						|
 | 
						|
import os
 | 
						|
import re
 | 
						|
import sys
 | 
						|
import sets
 | 
						|
import pydoc
 | 
						|
import pprint
 | 
						|
import socket
 | 
						|
import logging
 | 
						|
import optparse
 | 
						|
from itertools import imap
 | 
						|
 | 
						|
import ansi
 | 
						|
import utils
 | 
						|
import ircutils
 | 
						|
import registry
 | 
						|
 | 
						|
import questions
 | 
						|
from questions import output, yn, anything, something, expect, getpass
 | 
						|
 | 
						|
def getPlugins(pluginDirs):
 | 
						|
    filenames = []
 | 
						|
    for pluginDir in pluginDirs:
 | 
						|
        try:
 | 
						|
            filenames.extend(os.listdir(pluginDir))
 | 
						|
        except OSError:
 | 
						|
            continue
 | 
						|
    plugins = sets.Set([])
 | 
						|
    for filename in filenames:
 | 
						|
        if filename.endswith('.py') and filename[0].isupper():
 | 
						|
            plugins.add(os.path.splitext(filename)[0])
 | 
						|
    plugins.discard('Owner')
 | 
						|
    plugins = list(plugins)
 | 
						|
    plugins.sort()
 | 
						|
    return plugins
 | 
						|
 | 
						|
def loadPlugin(name):
 | 
						|
    import Owner
 | 
						|
    try:
 | 
						|
        module = Owner.loadPluginModule(name)
 | 
						|
        if hasattr(module, 'Class'):
 | 
						|
            return module
 | 
						|
        else:
 | 
						|
            output("""That plugin loaded fine, but didn't seem to be a real
 | 
						|
            Supybot plugin; there was no Class variable to tell us what class
 | 
						|
            to load when we load the plugin.  We'll skip over it for now, but
 | 
						|
            you can always add it later.""")
 | 
						|
            return None
 | 
						|
    except Exception, e:
 | 
						|
        output("""We encountered a bit of trouble trying to load plugin %r.
 | 
						|
        Python told us %r.  We'll skip over it for now, you can always add it
 | 
						|
        later.""" % (name, utils.exnToString(e)))
 | 
						|
        return None
 | 
						|
 | 
						|
def describePlugin(module, showUsage):
 | 
						|
    if module.__doc__:
 | 
						|
        output(module.__doc__, unformatted=False)
 | 
						|
    elif hasattr(module.Class, '__doc__'):
 | 
						|
        output(module.Class.__doc__, unformatted=False)
 | 
						|
    else:
 | 
						|
        output("""Unfortunately, this plugin doesn't seem to have any
 | 
						|
        documentation.  Sorry about that.""")
 | 
						|
    if showUsage:
 | 
						|
        if hasattr(module, 'example'):
 | 
						|
            if yn('This plugin has a usage example.  '
 | 
						|
                  'Would you like to see it?', default=False):
 | 
						|
                pydoc.pager(module.example)
 | 
						|
        else:
 | 
						|
            output("""This plugin has no usage example.""")
 | 
						|
    
 | 
						|
def clearLoadedPlugins(plugins, pluginRegistry):
 | 
						|
    for plugin in plugins:
 | 
						|
        try:
 | 
						|
            pluginKey = pluginRegistry.getChild(plugin)
 | 
						|
            if pluginKey():
 | 
						|
                plugins.remove(plugin)
 | 
						|
        except KeyError:
 | 
						|
            continue
 | 
						|
 | 
						|
_windowsVarRe = re.compile(r'%(\w+)%')
 | 
						|
def getDirectoryName(default):
 | 
						|
    done = False
 | 
						|
    while not done:
 | 
						|
        dir = something('What directory do you want to use?',
 | 
						|
                       default=os.path.join(os.curdir, default))
 | 
						|
        dir = os.path.expanduser(dir)
 | 
						|
        dir = _windowsVarRe.sub(r'$\1', dir)
 | 
						|
        dir = os.path.expandvars(dir)
 | 
						|
        dir = os.path.abspath(dir)
 | 
						|
        try:
 | 
						|
            os.makedirs(dir)
 | 
						|
            done = True
 | 
						|
        except OSError, e:
 | 
						|
            if e.args[0] != 17: # File exists.
 | 
						|
                output("""Sorry, I couldn't make that directory for some
 | 
						|
                reason.  The Operating System told me %s.  You're going to
 | 
						|
                have to pick someplace else.""" % e)
 | 
						|
            else:
 | 
						|
                done = True
 | 
						|
    return os.path.expandvars(os.path.expanduser(dir))
 | 
						|
 | 
						|
def getRegistryValue(setting, prompt='', showHelp=True, showType=True):
 | 
						|
    if not prompt:
 | 
						|
        prompt = 'What would you like to set this option to?'
 | 
						|
    if showHelp:
 | 
						|
        help = ''
 | 
						|
        if showType:
 | 
						|
            help = '%s:   ' % type(setting).__name__
 | 
						|
        help = '%s%s' % (help, setting.help)
 | 
						|
        output(textwrap.fill(help), unformatted=False)
 | 
						|
    ret = None
 | 
						|
    while not ret:
 | 
						|
        try:
 | 
						|
            setting.set(expect(prompt, [], default=str(setting)))
 | 
						|
            ret = setting()
 | 
						|
        except registry.InvalidRegistryValue, reason:
 | 
						|
            output(str(reason))
 | 
						|
    return ret
 | 
						|
 | 
						|
def main():
 | 
						|
    from conf import version
 | 
						|
    parser = optparse.OptionParser(usage='Usage: %prog [options] [configFile]',
 | 
						|
                                   version='Supybot %s' % version)
 | 
						|
    (options, args) = parser.parse_args()
 | 
						|
    
 | 
						|
    filename = ''
 | 
						|
    if len(args) > 1:
 | 
						|
        parser.error()
 | 
						|
    elif len(args) == 1:
 | 
						|
        filename = args[0]
 | 
						|
        try:
 | 
						|
            registry.open(filename)
 | 
						|
        except OSError, msg:
 | 
						|
            raise SystemExit, 'Unable to open file %s: %s' % (filename, msg)
 | 
						|
        output("""It seems you already have a configuration file. We'll run
 | 
						|
        you through the options so you can change them if you want.""")
 | 
						|
    else:
 | 
						|
        output("""This is a wizard to help you start running supybot.  What it
 | 
						|
        will do is create a single Python file whose effect will be that of
 | 
						|
        starting an IRC bot with the options you select here.  So hold on tight
 | 
						|
        and be ready to be interrogated :)""")
 | 
						|
 | 
						|
 | 
						|
    output("""First of all, we can bold the questions you're asked so you can
 | 
						|
    easily distinguish the mostly useless blather (like this) from the
 | 
						|
    questions that you actually have to answer.""")
 | 
						|
    if yn('Would you like to try this bolding?', default=True):
 | 
						|
        questions.useBold = True
 | 
						|
        if not yn('Do you see this in bold?'):
 | 
						|
            output("""Sorry, it looks like your terminal isn't ANSI compliant.
 | 
						|
            Try again some other day, on some other terminal :)""")
 | 
						|
            questions.useBold = False
 | 
						|
        else:
 | 
						|
            output("""Great!""")
 | 
						|
 | 
						|
    ###
 | 
						|
    # Preliminary questions.
 | 
						|
    ###
 | 
						|
    output("""We've got some preliminary things to get out of the way before
 | 
						|
    we can really start asking you questions that directly relate to what your
 | 
						|
    bot is going to be like.""")
 | 
						|
 | 
						|
    # Advanced?
 | 
						|
    output("""We want to know if you consider yourself an advanced Supybot
 | 
						|
    user because some questions are just utterly boring and useless for new
 | 
						|
    users.  Others might not make sense unless you've used Supybot for some
 | 
						|
    time.""")
 | 
						|
    advanced = yn('Are you an advanced Supybot user?', default=False)
 | 
						|
    
 | 
						|
    ### Directories.
 | 
						|
    # We set these variables in cache because otherwise conf and log will
 | 
						|
    # create directories for the default values, which might not be what the
 | 
						|
    # user wants.
 | 
						|
    output("""Now we've got to ask you some questions about where some of
 | 
						|
    your directories are (or, perhaps, will be :)).  If you're running this
 | 
						|
    wizard from the directory you'll actually be starting your bot from and
 | 
						|
    don't mind creating some directories in the current directory, then just
 | 
						|
    don't give answers to these questions and we'll create the directories we
 | 
						|
    need right here in this directory.""")
 | 
						|
 | 
						|
    # conf.supybot.directories.log
 | 
						|
    output("""Your bot will need to put his logs somewhere.  Do you have any
 | 
						|
    specific place you'd like them?  If not, just press enter and we'll make
 | 
						|
    a directory named "logs" right here.""")
 | 
						|
    try:
 | 
						|
        logDir = registry._cache['supybot.directories.log']
 | 
						|
        logDir = utils.safeEval(logDir)
 | 
						|
        logDir = getDirectoryName(logDir)
 | 
						|
    except KeyError:
 | 
						|
        logDir = getDirectoryName('logs')
 | 
						|
    registry._cache['supybot.directories.log'] = logDir
 | 
						|
    
 | 
						|
 | 
						|
    # conf.supybot.directories.data
 | 
						|
    output("""Your bot will need to put various data somewhere.  Things like
 | 
						|
    databases, downloaded files, etc.  Do you have any specific place you'd
 | 
						|
    like the bot to put these things?  If not, just press enter and we'll make
 | 
						|
    a directory named "data" right here.""")
 | 
						|
    try:
 | 
						|
        dataDir = registry._cache['supybot.directories.data']
 | 
						|
        dataDir = utils.safeEval(dataDir)
 | 
						|
        dataDir = getDirectoryName(dataDir)
 | 
						|
    except KeyError:
 | 
						|
        dataDir = getDirectoryName('data')
 | 
						|
    registry._cache['supybot.directories.data'] = dataDir
 | 
						|
 | 
						|
    # conf.supybot.directories.conf
 | 
						|
    output("""Your bot must know where to find his configuration files.  It'll
 | 
						|
    probably only make one or two, but it's gotta have some place to put them.
 | 
						|
    Where should that place be?  If you don't care, just press enter and we'll
 | 
						|
    make a directory right here named "conf" where it'll store his stuff. """)
 | 
						|
    try:
 | 
						|
        confDir = registry._cache['supybot.directories.conf']
 | 
						|
        confDir = utils.safeEval(confDir)
 | 
						|
        confDir = getDirectoryName(confDir)
 | 
						|
    except KeyError:
 | 
						|
        confDir = getDirectoryName('conf')
 | 
						|
    registry._cache['supybot.directories.conf'] = confDir
 | 
						|
    
 | 
						|
    # Store the minimum log priority if set, because we set it to a temporary
 | 
						|
    # value during the wizard
 | 
						|
    try:
 | 
						|
        priority = registry._cache['supybot.log.minimumPriority']
 | 
						|
    except KeyError:
 | 
						|
        priority = 'INFO'
 | 
						|
    registry._cache['supybot.log.minimumPriority'] = 'CRITICAL'
 | 
						|
    
 | 
						|
    # Now that we're all set, import conf and log
 | 
						|
    import conf
 | 
						|
    import log
 | 
						|
 | 
						|
    # pluginDirs
 | 
						|
    output("""Your bot will also need to know where to find his plugins at.
 | 
						|
    Of course, he already knows where the plugins that he came with are, but
 | 
						|
    your own personal plugins that you write for will probably be somewhere
 | 
						|
    else.""")
 | 
						|
    pluginDirs = conf.supybot.directories.plugins()
 | 
						|
    output("""Currently, the bot knows about the following directories:""")
 | 
						|
    output(utils.commaAndify(pluginDirs))
 | 
						|
    while yn('Would you like to add another plugin directory?',
 | 
						|
             default=False):
 | 
						|
        pluginDir = getDirectoryName('plugins')
 | 
						|
        if pluginDir not in pluginDirs:
 | 
						|
            pluginDirs.append(pluginDir)
 | 
						|
    conf.supybot.directories.plugins.setValue(pluginDirs)
 | 
						|
 | 
						|
    output("Good!  We're done with the directory stuff.")
 | 
						|
 | 
						|
    ###
 | 
						|
    # Bot stuff
 | 
						|
    ###
 | 
						|
    output("""Now we're going to ask you things that actually relate to the
 | 
						|
    bot you'll be running.""")
 | 
						|
 | 
						|
    # conf.supybot.server
 | 
						|
    # Force the user into specifying a server if he didn't have one already
 | 
						|
    try:
 | 
						|
        defaultServer = registry._cache['supybot.server']
 | 
						|
        defaultServer = utils.safeEval(defaultServer)
 | 
						|
        defaultServer = defaultServer.split(':')[0]
 | 
						|
    except KeyError:
 | 
						|
        defaultServer = None
 | 
						|
    server = None
 | 
						|
    while not server:
 | 
						|
        serverString = something('What server would you like to connect to?',
 | 
						|
                                 default=defaultServer)
 | 
						|
        try:
 | 
						|
            output("""Looking up %s...""" % serverString)
 | 
						|
            ip = socket.gethostbyname(serverString)
 | 
						|
        except:
 | 
						|
            output("""Sorry, I couldn't find that server.  Perhaps you
 | 
						|
            misspelled it?""")
 | 
						|
            continue
 | 
						|
        output("""Found %s (%s).""" % (serverString, ip))
 | 
						|
        output("""IRC Servers almost always accept connections on port
 | 
						|
        6667.  They can, however, accept connections anywhere their admin
 | 
						|
        feels like he wants to accept connections from.""")
 | 
						|
        if yn('Does this server require connection on a non-standard port?',
 | 
						|
              default=False):
 | 
						|
            port = 0
 | 
						|
            while not port:
 | 
						|
                port = something('What port is that?')
 | 
						|
                try:
 | 
						|
                    i = int(port)
 | 
						|
                    if not (0 < i < 65536):
 | 
						|
                        raise ValueError
 | 
						|
                except ValueError:
 | 
						|
                    output("""That's not a valid port.""")
 | 
						|
                    port = 0
 | 
						|
        else:
 | 
						|
            port = 6667
 | 
						|
        server = ':'.join(map(str, [serverString, port]))
 | 
						|
    conf.supybot.server.set(server)
 | 
						|
 | 
						|
    # conf.supybot.nick
 | 
						|
    # Force the user into specifying a nick if he didn't have one already
 | 
						|
    try:
 | 
						|
        defaultNick = registry._cache['supybot.nick']
 | 
						|
        defaultNick = utils.safeEval(defaultNick)
 | 
						|
    except KeyError:
 | 
						|
        defaultNick = None
 | 
						|
    while True:
 | 
						|
        nick = something('What nick would you like your bot to use?',
 | 
						|
                         default=defaultNick)
 | 
						|
        try:
 | 
						|
            conf.supybot.nick.set(nick)
 | 
						|
            break
 | 
						|
        except registry.InvalidRegistryValue:
 | 
						|
            output("""That's not a valid nick.  Go ahead and pick another.""")
 | 
						|
 | 
						|
    # conf.supybot.user
 | 
						|
    output("""If you've ever done a /whois on a person, you know that IRC
 | 
						|
    provides a way for users to show the world their full name.  What would
 | 
						|
    you like your bot's full name to be?  If you don't care, just press
 | 
						|
    enter and it'll be the same as your bot's nick.""")
 | 
						|
    user = ''
 | 
						|
    try:
 | 
						|
        defaultUser = registry._cache['supybot.user']
 | 
						|
        defaultUser = utils.safeEval(defaultUser)
 | 
						|
    except KeyError:
 | 
						|
        defaultUser = nick
 | 
						|
    user = something('What would you like your bot\'s full name to be?',
 | 
						|
                     default=defaultUser)
 | 
						|
    conf.supybot.user.set(user)
 | 
						|
 | 
						|
    # conf.supybot.ident (if advanced)
 | 
						|
    try:
 | 
						|
        defaultIdent = registry._cache['supybot.ident']
 | 
						|
        defaultIdent = utils.safeEval(defaultIdent)
 | 
						|
    except KeyError:
 | 
						|
        defaultIdent = nick
 | 
						|
    if advanced:
 | 
						|
        output("""IRC servers also allow you to set your ident, which they
 | 
						|
        might need if they can't find your identd server.  What would you
 | 
						|
        like your ident to be?  If you don't care, press enter and we'll
 | 
						|
        use the same string as your bot's nick.""")
 | 
						|
        while True:
 | 
						|
            ident = something('What would you like your bot\'s ident to be?',
 | 
						|
                              default=defaultIdent)
 | 
						|
            try:
 | 
						|
                conf.supybot.ident.set(ident)
 | 
						|
                break
 | 
						|
            except registry.InvalidRegistryValue:
 | 
						|
                output("""That was not a valid ident.
 | 
						|
                       Go ahead and pick another.""")
 | 
						|
    else:
 | 
						|
        conf.supybot.ident.set(defaultIdent)
 | 
						|
 | 
						|
    # conf.supybot.password
 | 
						|
    output("""Some servers require a password to connect to them.  Most
 | 
						|
    public servers don't.  If you try to connect to a server and for some
 | 
						|
    reason it just won't work, it might be that you need to set a
 | 
						|
    password.""")
 | 
						|
    if yn('Do you want to set such a password?', default=False):
 | 
						|
        conf.supybot.password.set(getpass())
 | 
						|
 | 
						|
    # conf.supybot.channels
 | 
						|
    output("""Of course, having an IRC bot isn't the most useful thing in the
 | 
						|
    world unless you can make that bot join some channels.""")
 | 
						|
    if yn('Do you want your bot to join some channels when he connects?',
 | 
						|
          default=True):
 | 
						|
        defaultChannels = ','.join(conf.supybot.channels())
 | 
						|
        channels = something('What channels?  Separate channels with '
 | 
						|
                             'commas.', default=defaultChannels)
 | 
						|
        while not all(ircutils.isChannel, channels.split(',')):
 | 
						|
            # FIXME: say which ones weren't channels.
 | 
						|
            output("""Not all of those are valid IRC channels.  Be sure to
 | 
						|
            prefix the channel with # (or +, or !, or &, but no one uses those
 | 
						|
            channels, really).""")
 | 
						|
            channels = something('What channels?',
 | 
						|
                                 default=defaultChannels)
 | 
						|
    conf.supybot.channels.set(channels)
 | 
						|
 | 
						|
    ###
 | 
						|
    # Plugins
 | 
						|
    ###
 | 
						|
    def configurePlugin(module, advanced):
 | 
						|
        if hasattr(module, 'configure'):
 | 
						|
            output("""Beginning configuration for %s..."""%module.Class.__name__)
 | 
						|
            module.configure(advanced)
 | 
						|
            print # Blank line :)
 | 
						|
            output("""Done!""")
 | 
						|
        else:
 | 
						|
            conf.registerPlugin(module, currentValue=True)
 | 
						|
 | 
						|
    plugins = getPlugins(pluginDirs)
 | 
						|
    for s in ('Admin', 'User', 'Channel', 'Misc', 'Config'):
 | 
						|
        configurePlugin(s, advanced)
 | 
						|
    clearLoadedPlugins(plugins, conf.supybot.plugins)
 | 
						|
 | 
						|
    output("""Now we're going to run you through plugin configuration. There's
 | 
						|
           a variety of plugins in supybot by default, but you can create and
 | 
						|
           add your own, ofcourse. We'll allow you to take a look at the known
 | 
						|
           plugins' descriptions and configure them
 | 
						|
           if you like what you see.""")
 | 
						|
 | 
						|
    # bulk
 | 
						|
    addedBulk = False
 | 
						|
    if advanced and yn('Would you like to add plugins en masse first?'):
 | 
						|
        addedBulk = True
 | 
						|
        output("""The available plugins are: %s.""" % \
 | 
						|
                                                   utils.commaAndify(plugins))
 | 
						|
        output("""What plugins would you like to add?  If you've changed your
 | 
						|
        mind and would rather not add plugins in bulk like this, just press
 | 
						|
        enter and we'll move on to the individual plugin configuration.""")
 | 
						|
        massPlugins = anything('Separate plugin names by spaces:')
 | 
						|
        for name in re.split(r',?\s+', massPlugins):
 | 
						|
            module = loadPlugin(name)
 | 
						|
            if module is not None:
 | 
						|
                configurePlugin(module, advanced)
 | 
						|
                clearLoadedPlugins(plugins, conf.supybot.plugins)
 | 
						|
 | 
						|
    # individual
 | 
						|
    if yn('Would you like to look at plugins individually?'):
 | 
						|
        output("""Next comes your oppurtunity to learn more about the plugins
 | 
						|
        that are available and select some (or all!) of them to run in your
 | 
						|
        bot.  Before you have to make a decision, of course, you'll be able to
 | 
						|
        see a short description of the plugin and, if you choose, an example
 | 
						|
        session with the plugin.  Let's begin.""")
 | 
						|
        # until we get example strings again, this will default to false
 | 
						|
        #showUsage =yn('Would you like the option of seeing usage examples?')
 | 
						|
        showUsage = False
 | 
						|
        name = expect('What plugin would you like to look at?', plugins)
 | 
						|
        while name:
 | 
						|
            module = loadPlugin(name)
 | 
						|
            if module is not None:
 | 
						|
                describePlugin(module, showUsage)
 | 
						|
                if yn('Would you like to load this plugin?', default=True):
 | 
						|
                    configurePlugin(module, advanced)
 | 
						|
                    clearLoadedPlugins(plugins, conf.supybot.plugins)
 | 
						|
            if not yn('Would you like add another plugin?'):
 | 
						|
                break
 | 
						|
            name = expect('What plugin would you like to look at?', plugins)
 | 
						|
    
 | 
						|
    ###
 | 
						|
    # Sundry
 | 
						|
    ###
 | 
						|
    output("""Although supybot offers a supybot-adduser.py script, with which
 | 
						|
    you can add users to your bot's user database, it's *very* important that
 | 
						|
    you have an owner user for you bot.""")
 | 
						|
    if yn('Would you like to add an owner user for your bot?', default=True):
 | 
						|
        import ircdb
 | 
						|
        name = something('What should the owner\'s username be?')
 | 
						|
        try:
 | 
						|
            id = ircdb.users.getUserId(name)
 | 
						|
            u = ircdb.users.getUser(id)
 | 
						|
            if u.checkCapability('owner'):
 | 
						|
                output("""That user already exists, and has owner capabilities
 | 
						|
                already.  Perhaps you added it before? """)
 | 
						|
                if yn('Do you want to remove its owner capability?',
 | 
						|
                      default=False):
 | 
						|
                    u.removeCapability('owner')
 | 
						|
                    ircdb.users.setUser(id, u)
 | 
						|
            else:
 | 
						|
                output("""That user already exists, but doesn't have owner
 | 
						|
                capabilities.""")
 | 
						|
                if yn('Do you want to add to it owner capabilities?',
 | 
						|
                      default=False):
 | 
						|
                    u.addCapability('owner')
 | 
						|
                    ircdb.users.setUser(id, u)
 | 
						|
        except KeyError:
 | 
						|
            password = getpass('What should the owner\'s password be?')
 | 
						|
            (id, u) = ircdb.users.newUser()
 | 
						|
            u.name = name
 | 
						|
            u.setPassword(password)
 | 
						|
            u.addCapability('owner')
 | 
						|
            ircdb.users.setUser(id, u)
 | 
						|
 | 
						|
    output("""Of course, when you're in an IRC channel you can address the bot
 | 
						|
    by its nick and it will respond, if you give it a valid command (it may or
 | 
						|
    may not respond, depending on what your config variable replyWhenNotCommand
 | 
						|
    is set to).  But your bot can also respond to a short "prefix character,"
 | 
						|
    so instead of saying "bot: do this," you can say, "@do this" and achieve
 | 
						|
    the same effect.  Of course, you don't *have* to have a prefix char, but
 | 
						|
    if the bot ends up participating significantly in your channel, it'll ease
 | 
						|
    things.""")
 | 
						|
    if yn('Would you like to set the prefix char(s) for your bot?  ',
 | 
						|
          default=True):
 | 
						|
        output("""Enter any characters you want here, but be careful: they
 | 
						|
        should be rare enough that people don't accidentally address the bot
 | 
						|
        (simply because they'll probably be annoyed if they do address the bot
 | 
						|
        on accident).  You can even have more than one.  I (jemfinch) am quite
 | 
						|
        partial to @, but that's because I've been using it since my ocamlbot
 | 
						|
        days.""")
 | 
						|
        import callbacks
 | 
						|
        while True:
 | 
						|
            try:
 | 
						|
                conf.supybot.prefixChars.set(
 | 
						|
                                    something('What would you like your '
 | 
						|
                                    'bot\'s prefix character(s) to be?',
 | 
						|
                                    default='@'))
 | 
						|
                break
 | 
						|
            except registry.InvalidRegistryValue, reason:
 | 
						|
                output(str(reason))
 | 
						|
    else:
 | 
						|
        conf.supybot.prefixChars.set('')
 | 
						|
 | 
						|
    # enablePipeSyntax
 | 
						|
    output("""Supybot allows nested commands.  You've probably
 | 
						|
    read about them in our website or documentation, and almost certainly have
 | 
						|
    seen them in the plugin examples (if you chose to read them),  By default,
 | 
						|
    they work with a syntax that looks something like Lisp with square
 | 
						|
    brackets.  I.e., to call the command foo on the output of bar, you would
 | 
						|
    use "foo [bar]".  Supybot is also capable of providing a pipe syntax
 | 
						|
    similar to *nix pipes.  In addition to "foo [bar]", you could achieve the
 | 
						|
    same effect with "bar | foo", which some people find more natural.  This
 | 
						|
    syntax is disabled by default because so many people have pipes in their
 | 
						|
    nicks, and we've found it to be somewhat frustrating to have to quote such
 | 
						|
    nicks in commands.""")
 | 
						|
    conf.supybot.pipeSyntax.setValue(yn('Would you like to enable the pipe '
 | 
						|
                                 'syntax for nesting?  ', default=False))
 | 
						|
 | 
						|
    ###
 | 
						|
    # logging variables.
 | 
						|
    ###
 | 
						|
 | 
						|
    # conf.supybot.log.stdout
 | 
						|
    output("""By default, your bot will log not only to files in the logs
 | 
						|
    directory you gave it, but also to stdout.  We find this useful for
 | 
						|
    debugging, and also just for the pretty output (it's colored!)""")
 | 
						|
    conf.supybot.log.stdout.setValue(not yn('Would you like to turn off '
 | 
						|
                                     'this logging to stdout?', default=False))
 | 
						|
    if conf.supybot.log.stdout():
 | 
						|
        # conf.something
 | 
						|
        output("""Some terminals may not be able to display the pretty colors
 | 
						|
        logged to stderr.  By default, though, we turn the colors off for
 | 
						|
        Windows machines and leave it on for *nix machines.""")
 | 
						|
        if os.name is not 'nt':
 | 
						|
            conf.supybot.log.stdout.colorized.setValue(
 | 
						|
                not yn('Would you like to turn this colorization off?',
 | 
						|
                default=False))
 | 
						|
 | 
						|
    # conf.supybot.log.minimumPriority
 | 
						|
    output("""Your bot can handle debug messages at several priorities,
 | 
						|
    CRITICAL, in decreasing order of priority.  By
 | 
						|
    default, your bot will log all of these priorities.  You can, however,
 | 
						|
    specify that he only log messages above a certain priority level.  Of
 | 
						|
    course, all error messages will still be logged.""")
 | 
						|
    newPriority = something('What would you like the minimum priority to be?  '
 | 
						|
                         'Just press enter to accept the default.',
 | 
						|
                         default=priority).lower()
 | 
						|
    while newPriority not in ['debug', 'info', 'warning', 'error', 'critical']:
 | 
						|
        output("""That's not a valid priority.  Valid priorities include
 | 
						|
        'DEBUG', 'INFO', 'WARNING', 'ERROR', and 'CRITICAL'""")
 | 
						|
        newPriority = something('What would you like the minimum priority to '
 | 
						|
                             'be?  Just press enter to accept the default.',
 | 
						|
                             default=priority).lower()
 | 
						|
 | 
						|
    if advanced:
 | 
						|
        output("""Here's some stuff you only get to choose if you're an
 | 
						|
        advanced user :)""")
 | 
						|
 | 
						|
        # conf.supybot.reply.withNickPrefix
 | 
						|
        output("""By defualt, the bot will respond to all commands with a
 | 
						|
        Nick: <response> response.  That is, the user making the command will
 | 
						|
        have their nick prefixed to the command.
 | 
						|
        If supybot.reply.withNickPrefix is set to False, replies from the bot
 | 
						|
        will not include this nick prefix.""")
 | 
						|
        conf.supybot.reply.withNickPrefix.setValue(
 | 
						|
            not yn('Would you like to turn off this nick prefix?',
 | 
						|
            default=False))
 | 
						|
 | 
						|
        # conf.supybot.reply.whenAddressedByNick
 | 
						|
        output("""By default, the bot will respond when addressed by its nick.
 | 
						|
        That is, if the bot's nick is 'botnick', then 'botnick: foo' will call
 | 
						|
        the foo command.  If replyWhenAddressedByNick is False, the bot will
 | 
						|
        not respond to such messages.  Make sure you have a prefixChar set if
 | 
						|
        you set this, otherwise people will only be able to communicate with
 | 
						|
        the bot through private messages.""")
 | 
						|
        conf.supybot.reply.whenAddressedByNick.setValue(
 | 
						|
            not yn('Would you like to turn off the bot\'s replies to messages '
 | 
						|
                   'prefixed with its nick?', default=False))
 | 
						|
 | 
						|
        # conf.supybot.showSimpleSyntax
 | 
						|
        output("""By default, when the bot receives a message with invalid
 | 
						|
        arguments, the bot returns the full help (syntax and description) of
 | 
						|
        the command.  If showOnlySyntax is set to True, though, the bot will
 | 
						|
        return just the syntax of the command.  Of course, the help will still
 | 
						|
        be available via the help command.""")
 | 
						|
        conf.supybot.showSimpleSyntax.setValue(
 | 
						|
            yn('Would you like to show only the syntax of commands when '
 | 
						|
              'they\'re given invalid arguments?', default=False))
 | 
						|
 | 
						|
        # conf.supybot.reply.whenNotCommand
 | 
						|
        output("""By default, when people address your bot but don't give it
 | 
						|
        a valid command, it'll respond with a message saying that they didn't
 | 
						|
        give it a valid command.  When your channel grows more accustomed to
 | 
						|
        the bot, they may prefer that it not do that, since any command you
 | 
						|
        give the bot (at least within the included plugins) will respond with
 | 
						|
        something, so invalid commands are still noticeable.  This decreases
 | 
						|
        the channel traffic somewhat.""")
 | 
						|
        conf.supybot.reply.whenNotCommand.setValue(
 | 
						|
            not yn('Would you like to turn off the bot\'s replies when he\'s '
 | 
						|
              'addressed but given a non-command?', default=False))
 | 
						|
 | 
						|
        # conf.supybot.reply.withPrivateNotice
 | 
						|
        output("""When a user sends a command to the bot from within a
 | 
						|
        channel, the bot, by default, also responds to that channel. In some
 | 
						|
        rather busy channels this might be considered spam, especially if the
 | 
						|
        command returns several lines in its result. In this case you may want
 | 
						|
        to notice the user instead.""")
 | 
						|
        conf.supybot.reply.withPrivateNotice.setValue(
 | 
						|
            yn('Would you like the bot to notice replies to users in private '
 | 
						|
              'when a command is executed in a channel?', default=False))
 | 
						|
 | 
						|
        # conf.supybot.throttleTime
 | 
						|
        output("""In order to prevent flooding itself off the network,
 | 
						|
        your bot by default will not send more than one message per second to
 | 
						|
        the network.  This is, however, configurable.""")
 | 
						|
        if yn('Would you like to change the minimum amount of time between '
 | 
						|
              'messages your bot sends to the network?', default=False):
 | 
						|
            while True:
 | 
						|
                try:
 | 
						|
                    conf.supybot.throttleTime.set(something(
 | 
						|
                        'How long do you want your bot to wait between '
 | 
						|
                        'sending messages to the server?  Floating '
 | 
						|
                        'point values are accepted.'))
 | 
						|
                    break
 | 
						|
                except InvalidRegistryValue:
 | 
						|
                    output("""That's not a valid time.  You'll need to give
 | 
						|
                    a floating-point number.""")
 | 
						|
        
 | 
						|
    ###
 | 
						|
    # This is close to the end.
 | 
						|
    ###
 | 
						|
    if not advanced:
 | 
						|
        output("""There are a lot of options we didn't ask you about simply
 | 
						|
        because we'd rather you get up and running and have time left to play
 | 
						|
        around with your bot.  But come back and see us!  When you've played
 | 
						|
        around with your bot enough to know what you like, what you don't like,
 | 
						|
        what you'd like to change, then come back and run this script again
 | 
						|
        and tell us you're an advanced user.  Some of those questions might be
 | 
						|
        boring, but they'll really help you customize your bot :)""")
 | 
						|
    
 | 
						|
    ###
 | 
						|
    # Write the registry
 | 
						|
    ###
 | 
						|
    # Replace the temporary value in supybot.log.minimumPriority
 | 
						|
    conf.supybot.log.minimumPriority.set(newPriority)
 | 
						|
 | 
						|
    # Save the registry
 | 
						|
    if not filename:
 | 
						|
        filename = '%s.conf' % nick
 | 
						|
    registry.close(conf.supybot, filename)
 | 
						|
    
 | 
						|
    # FIXME: Prevent some INFO messages from being printed when exiting
 | 
						|
    
 | 
						|
    # Done!
 | 
						|
    output("""All done!  Your new bot configuration is %s.  If you're running 
 | 
						|
    a *nix based OS, you can probably start your bot with the command line
 | 
						|
    "supybot %s".  If you're not running a *nix or similar machine, you'll
 | 
						|
    just have to start it like you start all your other Python scripts.""" % \
 | 
						|
                                                         (filename, filename))
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    try:
 | 
						|
        main()
 | 
						|
    except KeyboardInterrupt:
 | 
						|
        # We may still be using bold text when exiting during a prompt
 | 
						|
        if questions.useBold:
 | 
						|
            import ansi
 | 
						|
            print ansi.RESET
 | 
						|
        print
 | 
						|
        print
 | 
						|
        output("""Well, it looks like you cancelled out of the wizard before
 | 
						|
        it was done.  Unfortunately, I didn't get to write anything to file.
 | 
						|
        Please run the wizard again to completion.""")
 |