Example #1
0
 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", "")
Example #2
0
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!")
Example #3
0
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