def get_configuration(options): """Get or create a configuration object from ``options``. :param options: argument parser's options :type options: ``argparse.Namespace`` :return: a configuration object :rtype: :class:`sopel.config.Config` This may raise a :exc:`sopel.config.ConfigurationError` if the configuration file is invalid. .. seealso:: The configuration file is loaded by :func:`~sopel.cli.run.utils.load_settings` or created using the configuration wizard. """ try: bot_config = utils.load_settings(options) except ConfigurationNotFound as error: print("Welcome to Sopel!\n" "I can't seem to find the configuration file, " "so let's generate it!\n") config_path = error.filename if not config_path.endswith('.cfg'): config_path = config_path + '.cfg' config_path = _create_config(config_path) # try to reload it now that it's created bot_config = Config(config_path) bot_config._is_daemonized = options.daemonize return bot_config
def get_configuration(options): """Get an instance of configuration from options. This may raise a ``sopel.config.ConfigurationError`` if the file is an invalid configuration file. """ config_name = options.config or 'default' config_path = find_config(DEFAULT_HOMEDIR, config_name) if not os.path.isfile(config_path): print("Welcome to Sopel!\n" "I can't seem to find the configuration file, " "so let's generate it!\n") if not config_path.endswith('.cfg'): config_path = config_path + '.cfg' config_path = _create_config(config_path) bot_config = Config(config_path) bot_config._is_daemonized = options.daemonize return bot_config
def get_configuration(options): """Get or create a configuration object from ``options``. :param options: argument parser's options :type options: ``argparse.Namespace`` :return: a configuration object :rtype: :class:`sopel.config.Config` This may raise a :exc:`sopel.config.ConfigurationError` if the configuration file is invalid. .. seealso:: The configuration file is loaded by :func:`~sopel.cli.run.utils.load_settings` or created using the configuration wizard. """ try: bot_config = utils.load_settings(options) except ConfigurationNotFound as error: print( "Welcome to Sopel!\n" "I can't seem to find the configuration file, " "so let's generate it!\n") config_path = error.filename if not config_path.endswith('.cfg'): config_path = config_path + '.cfg' config_path = _create_config(config_path) # try to reload it now that it's created bot_config = Config(config_path) bot_config._is_daemonized = options.daemonize return bot_config
def get_configuration(options): """Get an instance of configuration from options. This may raise a ``sopel.config.ConfigurationError`` if the file is an invalid configuration file. """ try: bot_config = utils.load_settings(options) except ConfigurationNotFound as error: print( "Welcome to Sopel!\n" "I can't seem to find the configuration file, " "so let's generate it!\n") config_path = error.filename if not config_path.endswith('.cfg'): config_path = config_path + '.cfg' config_path = _create_config(config_path) # try to reload it now that it's created bot_config = Config(config_path) bot_config._is_daemonized = options.daemonize return bot_config
def main(argv=None): global homedir # Step One: Parse The Command Line try: parser = argparse.ArgumentParser(description='Sopel IRC Bot', usage='%(prog)s [options]') parser.add_argument('-c', '--config', metavar='filename', help='use a specific configuration file') parser.add_argument("-d", '--fork', action="store_true", dest="daemonize", help="Daemonize sopel") parser.add_argument("-q", '--quit', action="store_true", dest="quit", help="Gracefully quit Sopel") parser.add_argument("-k", '--kill', action="store_true", dest="kill", help="Kill Sopel") parser.add_argument("-l", '--list', action="store_true", dest="list_configs", help="List all config files found") parser.add_argument("-m", '--migrate', action="store_true", dest="migrate_configs", help="Migrate config files to the new format") parser.add_argument('--quiet', action="store_true", dest="quiet", help="Supress all output") parser.add_argument('-w', '--configure-all', action='store_true', dest='wizard', help='Run the configuration wizard.') parser.add_argument('--configure-modules', action='store_true', dest='mod_wizard', help=( 'Run the configuration wizard, but only for the ' 'module configuration options.')) parser.add_argument('-v', '--version', action="store_true", dest="version", help="Show version number and exit") opts = parser.parse_args() # Step Two: "Do not run as root" checks. try: # Linux/Mac if os.getuid() == 0 or os.geteuid() == 0: stderr('Error: Do not run Sopel with root privileges.') sys.exit(1) except AttributeError: # Windows if os.environ.get("USERNAME") == "Administrator": stderr('Error: Do not run Sopel as Administrator.') sys.exit(1) if opts.version: py_ver = '%s.%s.%s' % (sys.version_info.major, sys.version_info.minor, sys.version_info.micro) print('Sopel %s (running on python %s)' % (__version__, py_ver)) print('http://sopel.chat/') return elif opts.wizard: _wizard('all', opts.config) return elif opts.mod_wizard: _wizard('mod', opts.config) return if opts.list_configs: configs = enumerate_configs() print('Config files in ~/.sopel:') if len(configs) is 0: print('\tNone found') else: for config in configs: print('\t%s' % config) print('-------------------------') return config_name = opts.config or 'default' configpath = find_config(config_name) if not os.path.isfile(configpath): print("Welcome to Sopel!\nI can't seem to find the configuration file, so let's generate it!\n") if not configpath.endswith('.cfg'): configpath = configpath + '.cfg' _create_config(configpath) configpath = find_config(config_name) try: config_module = Config(configpath) except ConfigurationError as e: stderr(e) sys.exit(2) if config_module.core.not_configured: stderr('Bot is not configured, can\'t start') # exit with code 2 to prevent auto restart on fail by systemd sys.exit(2) logfile = os.path.os.path.join(config_module.core.logdir, 'stdio.log') config_module._is_daemonized = opts.daemonize sys.stderr = tools.OutputRedirect(logfile, True, opts.quiet) sys.stdout = tools.OutputRedirect(logfile, False, opts.quiet) # Handle --quit, --kill and saving the PID to file pid_dir = config_module.core.pid_dir if opts.config is None: pid_file_path = os.path.join(pid_dir, 'sopel.pid') else: basename = os.path.basename(opts.config) if basename.endswith('.cfg'): basename = basename[:-4] pid_file_path = os.path.join(pid_dir, 'sopel-%s.pid' % basename) if os.path.isfile(pid_file_path): with open(pid_file_path, 'r') as pid_file: try: old_pid = int(pid_file.read()) except ValueError: old_pid = None if old_pid is not None and tools.check_pid(old_pid): if not opts.quit and not opts.kill: stderr('There\'s already a Sopel instance running with this config file') stderr('Try using the --quit or the --kill options') sys.exit(1) elif opts.kill: stderr('Killing the sopel') os.kill(old_pid, signal.SIGKILL) sys.exit(0) elif opts.quit: stderr('Signaling Sopel to stop gracefully') if hasattr(signal, 'SIGUSR1'): os.kill(old_pid, signal.SIGUSR1) else: os.kill(old_pid, signal.SIGTERM) sys.exit(0) elif old_pid is None or (not tools.check_pid(old_pid) and (opts.kill or opts.quit)): stderr('Sopel is not running!') sys.exit(1) elif opts.quit or opts.kill: stderr('Sopel is not running!') sys.exit(1) if opts.daemonize: child_pid = os.fork() if child_pid is not 0: sys.exit() with open(pid_file_path, 'w') as pid_file: pid_file.write(str(os.getpid())) # Step Five: Initialise And Run sopel run(config_module, pid_file_path) except KeyboardInterrupt: print("\n\nInterrupted") os._exit(1)