def prompt(description, default, vals=[]): """ Prompts for input. If the user just presses enter, default is assumed. If the possible values are defined in the optional third parameter, the entered value must be from that list, or the user will be prompted again. """ success = False if len(vals) > 0: if not default in vals: vals.append(default) vals.sort() prompt_str = '%s (%s) [%s] ' % (description, pretty_list(vals), default) else: prompt_str = '%s [%s] ' % (description, default) while not success: value = input(prompt_str) if value in vals: success = True elif len(value) < 1: # Assume default value = default success = True elif len(vals) < 1: # Value entered, no restrictions defined success = True else: print('Invalid value. Must be one of the following: ' + str(vals)) return value
def help(self, server, channel, nick, params): """ Usage: help PLUGIN [COMMAND] - prints a help message. If only PLUGIN is specified, you get general plugin information and a list of available commands. Otherwise, the help for the specific COMMAND of the PLUGIN is provided. If PLUGIN can't be found, I will look for a command with that name. """ if len(params) < 1: return clean_string(self.help.__doc__) if len(params) < 2: if params[0] in self.bot.plugins: # Plugin found help_msg = clean_string(self.bot.plugins[params[0]].__doc__ or \ 'Sorry, no help message available.') commands = sorted(list(name \ for name, member \ in inspect.getmembers(self.bot.plugins[params[0]]) if hasattr(member, '__annotations__') \ and 'command' in member.__annotations__)) if len(commands) > 0: help_msg += ' Commands: %s' % pretty_list(commands) return clean_string(help_msg) elif params[0] in self.bot.commands: # Command found return clean_string(getattr( self.bot.commands[params[0]], params[0]).__doc__ or \ 'Sorry, no help message available.') else: return 'Plugin or command "%s" not found.' % params[0] # Only Plugin->Command left now. Try to find it... if params[1] in self.bot.commands and \ self.bot.commands[params[1]].__class__.__name__.lower() \ == params[0]: return clean_string(getattr( self.bot.plugins[params[0]], params[1]).__doc__ or \ 'Sorry, no help message available.') # If everything fails: return 'Command "%s" from plugin "%s" not found.' % (params[1], params[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
def list_plugins(self, server, channel, nick, params): """ Lists all active plugins. Plugins on the global- or server-wide blacklist are not shown. """ return pretty_list(self.bot.plugins.keys())
def list_commands(self, server, channel, nick, params): """Lists all available commands.""" return pretty_list(self.bot.commands.keys())