Source code for plugins.command

# ../plugins/command.py

"""Provides a way to utilize sub-commands for a server command."""

# =============================================================================
# >> IMPORTS
# =============================================================================
# Source.Python Imports
#   Commands
from commands.typed import (
    TypedClientCommand, TypedSayCommand, TypedServerCommand,
)
#   Core
from core import AutoUnload
#   Cvars
from cvars.public import PublicConVar
#   Hooks
from hooks.exceptions import except_hooks
#   Paths
from paths import GAME_PATH
#   Plugins
from plugins import plugins_logger
from plugins import _plugin_strings
from plugins.manager import PluginFileNotFoundError
from plugins.manager import InvalidPluginName
from plugins.manager import PluginAlreadyLoaded
from plugins.manager import PluginHasBuiltInName
from plugins.manager import PluginNotLoaded


# =============================================================================
# >> ALL DECLARATION
# =============================================================================
__all__ = ('SubCommandManager',
           )


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the sp.plugins.command logger
plugins_command_logger = plugins_logger.command


# =============================================================================
# >> CLASSES
# =============================================================================
[docs]class SubCommandManager(AutoUnload, list): """Class used for executing sub-commands for the given console command."""
[docs] def __init__(self, manager, command, prefix='', logger=plugins_command_logger, translations=_plugin_strings): """Initializes the sub-command manager. :param PluginManager manager: A plugin manager. :param str command: Command to register. :param str prefix: Prefix used for printing messages to the console. :param Logger logger: A logger that is used for printing messages to the console. :param LangStrings translations: Translations used for printing messages to the console. The translations have to define the following messages: * Loading * Invalid Name * Already Loaded * No Module * Built-in * Unable to Load * Successful Load * Unloading * Not Loaded * Successful Unload * Plugins """ # Re-call OrderedDict's __init__ to properly setup the object super().__init__() self.manager = manager self._command = command self._prefix = prefix if prefix else '[{0}] '.format( self.command.upper()) self.logger = logger self.translations = translations
def _unload_instance(self): """Unload all sub-commands.""" for item in self: item._unload_instance() # Probably not necessary, but just in case... self.clear()
[docs] def server_sub_command(self, commands): """Add a server sub-command. .. seealso:: :class:`commands.typed.TypedServerCommand` """ if isinstance(commands, str): commands = [commands] command = TypedServerCommand([self._command] + list(commands)) self.append(command) return command
[docs] def client_sub_command(self, commands, permission=None): """Add a client sub-command. .. seealso:: :class:`commands.typed.TypedClientCommand` """ if isinstance(commands, str): commands = [commands] command = TypedClientCommand( [self._command] + list(commands), permission=permission, ) self.append(command) return command
[docs] def say_sub_command(self, commands, permission=None): """Add a say sub-command. .. seealso:: :class:`commands.typed.TypedSayCommand` """ if isinstance(commands, str): commands = [commands] command = TypedSayCommand( [self._command] + list(commands), permission=permission, ) self.append(command) return command
@property def command(self): """Return the server command registered to the class. :rtype: str """ return self._command @property def prefix(self): """Return the prefix to use in log messages. :rtype: str """ return self._prefix
[docs] def load_plugin(self, plugin_name): """Load a plugin by name. :param str plugin_name: Name of the plugin to load. :return: Return the loaded plugin. Return ``None`` on failure. :rtype: Plugin """ plugin = None self.log_message(self.translations[ 'Loading'].get_string(plugin=plugin_name)) try: plugin = self.manager.load(plugin_name) except InvalidPluginName: self.log_message(self.translations[ 'Invalid Name'].get_string(plugin=plugin_name)) except PluginAlreadyLoaded: self.log_message(self.translations[ 'Already Loaded'].get_string(plugin=plugin_name)) except PluginFileNotFoundError: self.log_message(self.translations[ 'No Module'].get_string( plugin=plugin_name, file=GAME_PATH.relpathto( self.manager.get_plugin_file_path( plugin_name)).replace('\\', '/'))) except PluginHasBuiltInName: self.log_message(self.translations[ 'Built-in'].get_string(plugin=plugin_name)) except: except_hooks.print_exception() self.log_message(self.translations[ 'Unable to Load'].get_string(plugin=plugin_name)) else: self.log_message(self.translations[ 'Successful Load'].get_string(plugin=plugin_name)) return plugin
[docs] def unload_plugin(self, plugin_name): """Unload a plugin by name. :param str plugin_name: Name of the plugin to unload. """ self.log_message(self.translations[ 'Unloading'].get_string(plugin=plugin_name)) try: self.manager.unload(plugin_name) except InvalidPluginName: self.log_message(self.translations[ 'Invalid Name'].get_string(plugin=plugin_name)) except PluginNotLoaded: self.log_message(self.translations[ 'Not Loaded'].get_string(plugin=plugin_name)) else: self.log_message(self.translations[ 'Successful Unload'].get_string(plugin=plugin_name))
[docs] def reload_plugin(self, plugin_name): """Reload a plugin by name. :param str plugin_name: Name of the plugin to reload. :return: Return the loaded plugin. Return ``None`` on failure. :rtype: Plugin """ self.unload_plugin(plugin_name) return self.load_plugin(plugin_name)
[docs] def print_plugins(self): """List all currently loaded plugins.""" # Get header messages message = self.translations[ 'Plugins'].get_string() + '\n' + '=' * 61 + '\n\n' # Loop through all loaded plugins for plugin_name in sorted(self.manager): info = self.manager[plugin_name].info message += plugin_name + ' ({}):\n'.format(info.verbose_name) if info.author is not None: message += ' author: {}\n'.format(info.author) if info.description is not None: message += ' description: {}\n'.format(info.description) if info.version != 'unversioned': message += ' version: {}\n'.format(info.version) if info.url is not None: message += ' url: {}\n'.format(info.url) if info.permissions: message += ' permissions:\n' for permission, description in info.permissions: message += ' {}:'.format(permission).ljust(30) + description + '\n' if isinstance(info.public_convar, PublicConVar): message += ' public convar: {}\n'.format(info.public_convar.name) for attr in info.display_in_listing: message += ' {}:'.format(attr).ljust(20) + str(getattr(info, attr)) + '\n' # Add 1 blank line between each plugin message += '\n' # Add the ending separator message += '=' * 61 # Print the message self.log_message(message)
[docs] def log_message(self, message): """Log a message. The prefix will be added automatically. :param str message: Message to log. """ self.logger.log_message(self.prefix + message, prepend_prefix=False)