mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-10-29 22:57:30 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			678 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			678 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| 
 | |
| import supybot
 | |
| 
 | |
| import fix
 | |
| 
 | |
| import re
 | |
| 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.get(plugin)
 | |
|             if pluginKey():
 | |
|                 plugins.remove(plugin)
 | |
|         except registry.NonExistentRegistryEntry:
 | |
|             continue
 | |
| 
 | |
| _windowsVarRe = re.compile(r'%(\w+)%')
 | |
| def getDirectoryName(default, basedir=os.curdir):
 | |
|     done = False
 | |
|     while not done:
 | |
|         dir = something('What directory do you want to use?',
 | |
|                        default=os.path.join(basedir, 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():
 | |
|     import log
 | |
|     import conf
 | |
|     log._stdoutHandler.setLevel(100) # *Nothing* gets through this!
 | |
|     parser = optparse.OptionParser(usage='Usage: %prog [options] [configFile]',
 | |
|                                    version='Supybot %s' % conf.version)
 | |
|     parser.add_option('', '--allow-root', action='store_true',
 | |
|                       dest='allowRoot',
 | |
|                       help='Determines whether the bot will be allowed to run'
 | |
|                            'as root.  You don\'t want this.  Don\'t do it.  '
 | |
|                            'Even if you think you want it, you don\'t.  '
 | |
|                            'You\'re probably dumb if you do this.')
 | |
|     (options, args) = parser.parse_args()
 | |
|     if os.name == 'posix':
 | |
|         if os.getuid() == 0 or os.geteuid() == 0 and not options.allowRoot:
 | |
|             sys.stderr.write('Please, don\'t run this as root.\n')
 | |
| 
 | |
|     filename = ''
 | |
|     if len(args) > 1:
 | |
|         parser.error('the wizard takes one argument at most.')
 | |
|     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')
 | |
|     conf.supybot.directories.log.setValue(logDir)
 | |
|     basedir = os.path.dirname(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, basedir=basedir)
 | |
|     except KeyError:
 | |
|         dataDir = getDirectoryName('data', basedir=basedir)
 | |
|     conf.supybot.directories.data.setValue(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, basedir=basedir)
 | |
|     except KeyError:
 | |
|         confDir = getDirectoryName('conf', basedir=basedir)
 | |
|     conf.supybot.directories.conf.setValue(confDir)
 | |
| 
 | |
|     # 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', basedir=basedir)
 | |
|         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
 | |
|     if advanced:
 | |
|         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())
 | |
|         output("""Seperate channels with spaces.  If the channel is locked
 | |
|                   with a key, follow the channel name with the key seperated
 | |
|                   by a comma. For example:
 | |
|                   #supybot #mychannel,mykey #otherchannel""");
 | |
|         while True:
 | |
|             channels = something('What channels?', default=defaultChannels)
 | |
|             try:
 | |
|                 conf.supybot.channels.set(channels)
 | |
|                 break
 | |
|             except registry.InvalidRegistryValue:
 | |
|                 # 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).""")
 | |
|     else:
 | |
|         conf.supybot.channels.setValue([])
 | |
| 
 | |
|     ###
 | |
|     # 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.__name__, currentValue=True)
 | |
| 
 | |
|     plugins = getPlugins(pluginDirs)
 | |
|     for s in ('Admin', 'User', 'Channel', 'Misc', 'Config'):
 | |
|         configurePlugin(loadPlugin(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, acceptEmpty=True)
 | |
|         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
 | |
|         c = ''
 | |
|         while not c:
 | |
|             try:
 | |
|                 c = anything('What would you like your bot\'s prefix '
 | |
|                              'character(s) to be?')
 | |
|                 conf.supybot.prefixChars.set(c)
 | |
|             except registry.InvalidRegistryValue, e:
 | |
|                 output(str(e))
 | |
|                 c = ''
 | |
|     else:
 | |
|         conf.supybot.prefixChars.set('')
 | |
| 
 | |
|     ###
 | |
|     # 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!)""")
 | |
|     stdout = not yn('Would you like to turn off this logging to stdout?')
 | |
|     conf.supybot.log.stdout.setValue(stdout)
 | |
|     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.level
 | |
|     output("""Your bot can handle debug messages at several priorities,
 | |
|     CRITICAL, ERROR, WARNING, INFO, and DEBUG, in decreasing order of priority.
 | |
|     By default, your bot will log all of these priorities except DEBUG.  You
 | |
|     can, however, specify that it only log messages above a certain priority
 | |
|     level.""")
 | |
|     priority = str(conf.supybot.log.level)
 | |
|     logLevel = something('What would you like the minimum priority to be?  '
 | |
|                          'Just press enter to accept the default.',
 | |
|                          default=priority).lower()
 | |
|     while logLevel not in ['debug', 'info', 'warning', 'error', 'critical']:
 | |
|         output("""That's not a valid priority.  Valid priorities include
 | |
|         'DEBUG', 'INFO', 'WARNING', 'ERROR', and 'CRITICAL'""")
 | |
|         logLevel = something('What would you like the minimum priority to '
 | |
|                              'be?  Just press enter to accept the default.',
 | |
|                              default=priority).lower()
 | |
|     conf.supybot.log.level.set(logLevel)
 | |
| 
 | |
|     if advanced:
 | |
|         output("""Here's some stuff you only get to choose if you're an
 | |
|         advanced user :)""")
 | |
| 
 | |
|         # enablePipeSyntax
 | |
|         output("""Supybot allows nested commands.  You've probably read about
 | |
|         them in our website or documentation.  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.""")
 | |
|         response = yn('Would you like to enable this pipe syntax?', default=0)
 | |
| 
 | |
|         # 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
 | |
|     ###
 | |
| 
 | |
|     # Save the registry
 | |
|     if not filename:
 | |
|         filename = '%s.conf' % nick
 | |
|     registry.close(conf.supybot, filename)
 | |
| 
 | |
|     # 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.""")
 | 
