Advertisement
MolSno

Untitled

Dec 5th, 2012
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.71 KB | None | 0 0
  1. #!/usr/bin/env python2.7
  2. # coding=utf-8
  3. """
  4. Willie - An IRC Bot
  5. Copyright 2008, Sean B. Palmer, inamidst.com
  6. Copyright © 2012, Elad Alfassa <[email protected]>
  7. Licensed under the Eiffel Forum License 2.
  8.  
  9. http://willie.dftba.net
  10. """
  11.  
  12. import sys
  13. import os
  14. import optparse
  15. import signal
  16. import imp
  17. try:
  18.     from willie.__init__ import run
  19.     from willie.config import Config, create_config, ConfigurationError, wizard
  20.     import willie.tools as tools
  21.     from willie.tools import stderr, stdout
  22. except ImportError:
  23.     from __init__ import run
  24.     from config import Config, create_config, ConfigurationError
  25.     import tools
  26.     from tools import stderr, stdout
  27.  
  28. willie_dotdir = os.path.expanduser('~/.willie')
  29. jenni_dotdir = os.path.expanduser('~/.jenni')
  30. phenny_dotdir = os.path.expanduser('~/.phenny')
  31. dotdir = willie_dotdir
  32.  
  33. def check_python_version():
  34.     if sys.version_info < (2, 7):
  35.         stderr('Error: Requires Python 2.7 or later. Try python2.7 willie')
  36.         sys.exit(1)
  37.  
  38. def enumerate_configs(extension='.cfg'):
  39.     willie_config = []
  40.     jenni_config = []
  41.     phenny_config = []
  42.     if os.path.isdir(willie_dotdir):
  43.         willie_dotdirfiles = os.listdir(willie_dotdir) #Preferred
  44.         for item in willie_dotdirfiles:
  45.             if item.endswith(extension):
  46.                 willie_config.append(item)
  47.     if os.path.isdir(jenni_dotdir):
  48.         jenni_dotdirfiles = os.listdir(jenni_dotdir) #Fallback
  49.         for item in jenni_dotdirfiles:
  50.             if item.endswith(extension):
  51.                 jenni_config.append(item)
  52.     if os.path.isdir(phenny_dotdir):
  53.         phenny_dotdirfiles = os.listdir(phenny_dotdir) #Fallback of fallback
  54.         for item in phenny_dotdirfiles:
  55.             willie_config = []
  56.             if item.endswith(extension):
  57.                 phenny_config.append(item)
  58.  
  59.     return (willie_config, jenni_config, phenny_config)
  60.  
  61. def find_config(name, extension='.cfg'):
  62.     global dotdir
  63.     configs = enumerate_configs(extension)
  64.     if name in configs[0] or name+extension in configs[0]:
  65.         dotdir = willie_dotdir
  66.         if name+extension in configs[0]:
  67.             name = name+extension
  68.     elif name in configs[1] or name+extension in configs[1]:
  69.         dotdir = jenni_dotdir
  70.         if name+extension in configs[1]:
  71.             name = name+extension
  72.     elif name in configs[2] or name+extension in configs[2]:
  73.         dotdir = phenny_dotdir
  74.         if name+extension in configs[2]:
  75.             name = name+extension
  76.     elif not name.endswith(extension):
  77.         name = name+extension
  78.  
  79.     return os.path.join(dotdir, name)
  80.  
  81. def main(argv=None):
  82.     # Step One: Parse The Command Line
  83.     try:
  84.         parser = optparse.OptionParser('%prog [options]')
  85.         parser.add_option('-c', '--config', metavar='filename', help='use a specific configuration file')
  86.         parser.add_option("-d", '--fork', action="store_true", dest="deamonize", help="Deamonize willie")
  87.         parser.add_option("-q", '--quit', action="store_true", dest="quit", help="Gracefully quit Willie")
  88.         parser.add_option("-k", '--kill', action="store_true", dest="kill", help="Kill Willie")
  89.         parser.add_option("-l", '--list', action="store_true", dest="list_configs", help="List all config files found")
  90.         parser.add_option("-m", '--migrate', action="store_true", dest="migrate_configs", help="Migrate config files to the new format")
  91.         parser.add_option('--quiet', action="store_true", dest="quiet", help="Supress all output")
  92.         parser.add_option('-w', '--configure-all', action='store_true', dest='wizard', help='Run the configuration wizard.')
  93.         parser.add_option('--configure-modules', action='store_true', dest='mod_wizard', help='Run the configuration wizard, but only for the module configuration options.')
  94.         parser.add_option('--configure-database', action='store_true', dest='db_wizard', help='Run the configuration wizard, but only for the database configuration options.')
  95.         opts, args = parser.parse_args(argv)
  96.  
  97.         if opts.wizard:
  98.             wizard('all', opts.config)
  99.             return
  100.         elif opts.mod_wizard:
  101.             wizard('mod', opts.config)
  102.             return
  103.         elif opts.db_wizard:
  104.             wizard('db', opts.config)
  105.             return
  106.                    
  107.         check_python_version()
  108.         if opts.list_configs is not None:
  109.             configs = enumerate_configs()
  110.             stdout('Config files in ~/.willie:')
  111.             if len(configs[0]) is 0:
  112.                 stdout('\tNone found')
  113.             else:
  114.                 for config in configs[0]:
  115.                     stdout('\t%s' % config)
  116.             stdout('-------------------------')
  117.             stdout('Config files in ~/.jenni:')
  118.             if len(configs[1]) is 0:
  119.                 stdout('\tNone found')
  120.             else:
  121.                 for config in configs[1]:
  122.                     stdout('\t%s' % config)
  123.             stdout('-------------------------')
  124.             stdout('Config files in ~/.phenny:')
  125.             if len(configs[2]) is 0:
  126.                 stdout('\tNone found')
  127.             else:
  128.                 for config in configs[2]:
  129.                     stdout('\t%s' % config)
  130.             stdout('-------------------------')
  131.             return
  132.  
  133.         config_name = opts.config or 'default'
  134.        
  135.         if opts.migrate_configs is not None:
  136.             configpath = find_config(config_name, '.py')
  137.             new_configpath = configpath[:-2]+'cfg'
  138.             if os.path.isfile(new_configpath):
  139.                 valid_answer = False
  140.                 while not valid_answer:
  141.                     answer = raw_input('Warning, new config file already exists. Overwrite? [y/n]')
  142.                     if answer is 'n' or answer == 'no':
  143.                         return
  144.                     elif answer == 'y' or answer == 'yes':
  145.                         valid_answer = True
  146.             old_cfg = imp.load_source('Config', configpath)
  147.             new_cfg = Config(new_configpath, load=False)
  148.             new_cfg.add_section('core')
  149.             for attrib in dir(old_cfg):
  150.                 if not attrib.startswith('_'):
  151.                     value = getattr(old_cfg, attrib)
  152.                     if value is None:
  153.                         continue #Skip NoneTypes
  154.                     if type(value) is list: #Parse lists
  155.                         parsed_value = ','.join(value)
  156.                     else:
  157.                         parsed_value = str(value)
  158.                     if attrib == 'password':
  159.                         attrib = 'nickserv_password'
  160.                     if attrib == 'serverpass':
  161.                         attrib = 'server_password'
  162.                     setattr(new_cfg.core, attrib, parsed_value)
  163.             new_cfg.save()
  164.             print 'Configuration migrated sucessfully, starting Willie'
  165.            
  166.        
  167.         configpath = find_config(config_name)
  168.         if not os.path.isfile(configpath):
  169.             stdout("Welcome to Willie!\nI can't seem to find the configuration file, so let's generate it!\n")
  170.             if not configpath.endswith('.cfg'):
  171.                 configpath = configpath + '.cfg'
  172.             create_config(configpath)
  173.             configpath = find_config(config_name)
  174.         try:
  175.             config_module = Config(configpath)
  176.         except ConfigurationError as e:
  177.             stderr(e)
  178.             sys.exit(1)
  179.         config_module.dotdir = dotdir
  180.  
  181.         if not config_module.core.logdir:
  182.             config_module.core.logdir = os.path.join(dotdir, 'logs')
  183.         logfile = os.path.os.path.join(config_module.logdir, 'stdio.log')
  184.         if not os.path.isdir(config_module.logdir):
  185.             os.mkdir(config_module.logdir)
  186.         if opts.quiet is None:
  187.             opts.quiet = False
  188.  
  189.         sys.stderr = tools.OutputRedirect(logfile, True, opts.quiet)
  190.         sys.stdout = tools.OutputRedirect(logfile, False, opts.quiet)
  191.  
  192.         #Handle --quit, --kill and saving the PID to file
  193.         if opts.config is None:
  194.             pid_file_path = os.path.join(dotdir, '.pid-default')
  195.         else:
  196.             pid_file_path = os.path.join(dotdir, '.pid-%s' % opts.config)
  197.         if os.path.isfile(pid_file_path):
  198.             pid_file = open(pid_file_path, 'r')
  199.             old_pid = int(pid_file.read())
  200.             pid_file.close()
  201.             if tools.check_pid(old_pid):
  202.                 if opts.quit is None and opts.kill is None:
  203.                     stderr('There\'s already a Willie instance running with this config file')
  204.                     stderr('Try using the --quit or the --kill options')
  205.                     sys.exit(1)
  206.                 elif opts.kill:
  207.                     stderr('Killing the willie')
  208.                     os.kill(old_pid, signal.SIGKILL)
  209.                     sys.exit(0)
  210.                 elif opts.quit:
  211.                     stderr('Singaling Willie to stop gracefully')
  212.                     os.kill(old_pid, signal.SIGUSR1)
  213.                     sys.exit(0)
  214.             elif not tools.check_pid(old_pid) and (opts.kill or opts.quit):
  215.                 stderr('Willie is not running!')
  216.                 sys.exit(1)
  217.         elif opts.quit is not None or opts.kill is not None:
  218.             stderr('Willie is not running!')
  219.             sys.exit(1)
  220.         if opts.deamonize is not None:
  221.             child_pid = os.fork()
  222.             if child_pid is not 0:
  223.                 sys.exit()
  224.         pid_file = open(pid_file_path, 'w')
  225.         pid_file.write(str(os.getpid()))
  226.         pid_file.close()
  227.         config_module.pid_file_path = pid_file_path
  228.  
  229.         # Step Five: Initialise And Run willie
  230.         run(config_module)
  231.     except KeyboardInterrupt:
  232.         stdout("\n\nInterrupted")
  233.         os._exit(1)
  234. if __name__ == '__main__':
  235.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement