def load_config(self, config): self.config = config self.home = self.config.get("General", "home") or "" info("Bot home: " + self.home) self.global_plugin_blacklist = self.config.get("General", "plugin_blacklist").split(",") or [] info("Global plugin blacklist: " + str(self.global_plugin_blacklist)) self.signal_character = self.config.get("General", "signal_character") or "+" info("Signal character: " + self.signal_character) self.master = read_or_default(self.config, self.client.host, "master", "")
def main(): argparser = argparse.ArgumentParser(description="P1tr TNG - IRC bot.") argparser.add_argument("-c", "--conf", help="path to configuration file", action="store", default="config.cfg") argparser.add_argument( "-m", "--mkconf", help="launches the configuration wizard", action="store_const", const=True, default=False ) argparser.add_argument( "-t", "--test", help="runs plugin test suites and exits afterwards. Requires valid \ configuration", action="store_const", const=True, default=False, ) args = argparser.parse_args() clients = dict() connections = dict() config_path = args.conf # Launch configuration wizard, if desired, before bot launch if args.mkconf: config_path = config_wizard() config_loaded = False while not config_loaded: try: config = load_config(config_path) config_loaded = True except BotError: error("No configuration file at the given path. Starting wizard...") config_path = config_wizard() loglevel = read_or_default(config, "General", "loglevel", logging.ERROR, lambda val: getattr(logging, val)) set_loglevel(loglevel) # Run tests if the flag is set if args.test: run_tests(config) return # Exit after tests application = IRCApp() application.sleep_time = read_or_default(config, "General", "sleeptime", 0.2, lambda val: float(val)) info("Connecting to servers...") for section in config: if section != "General" and not "|" in section: try: clients[section] = IRCClient( BotHandler, host=section, port=config.getint(section, "port"), nick=config.get(section, "nick"), connect_cb=on_connect, ) clients[section].command_handler.load_config(config) clients[section].command_handler.load_plugins() application.addClient(clients[section], autoreconnect=True) except (KeyError, configparser.NoOptionError): pass # Not a server. except ValueError as ve: info("Config section " + section + " will be ignored: " + str(ve)) info("Startup complete.") try: application.run() except KeyboardInterrupt: for client in clients: clients[client].command_handler.exit() application.stop() info("All clients terminated. Goodbye!")
def discover_plugins(config): """ Finds the names of possible plugins, which can be found in the search directories. Locations are searched in the following order: Current working directory -> Bot home -> Bot install location Note that for each of the locations above, the "plugins" sub-directory is searched. Also note that when running P1tr standalone (not easy_install3'd), the bot install location is where you put the bot's Python files. If a plugin with the same name is found in two different locations, the one found first has precedence. This function does not load the plugins, just deliver a list of names! """ plugin_names = [] # Results if not config: # Config is essential to find all possible plugin dirs raise BotError("Cannot load plugins if the configuration has not \ been loaded yet.") home = read_or_default(config, 'General', 'home', '.') global_plugin_blacklist = read_or_default(config, 'General', 'plugin_blacklist', [], lambda val: val.split()) # Assemble search paths. If you need to add custom ones, just add them to # the path list below. The rest of the function can remain unchanged. paths = ['plugins', os.path.join(home, 'plugins')] try: # plugins folder is in p1tr.py's parent directory. paths.append(os.path.join( os.path.split( os.path.dirname(os.path.realpath(__main__.__file__)))[0], 'plugins')) except NameError: # __file__ is not defined in the python shell. warning('Cannot determine install directory. Ignoring.') paths = list(set(paths)) # Remove duplicates. debug('Plugin directories: %s' % pretty_list(paths)) # Search vor possible plugins for path in paths: plugin_dirs = [] try: # Check if valid path. plugin_dirs = os.listdir(path) except OSError: debug(path + ' is not a valid directory.') continue # Consider all directories plugins as long as they start with # a character. for plugin_dir_name in plugin_dirs: plugin_dir = os.path.join(path, plugin_dir_name) if not plugin_dir_name.lower()[0] in ascii_lowercase: debug(plugin_dir + ' is not a plugin directory.') continue if not os.path.isdir(plugin_dir): debug(plugin_dir + ' is not a plugin directory.') continue if plugin_dir_name in global_plugin_blacklist: debug(plugin_dir_name + ' is blacklisted globally.') continue # Skip plugins if one with the same name has already been loaded if plugin_dir_name in plugin_names: debug(plugin_dir_name + ' has been found before. Skipping.') continue # It passed all tests. It's most likely a plugin. plugin_names.append(plugin_dir_name) plugin_names.sort() return plugin_names