Skip to content
Snippets Groups Projects
plugins.py 3.05 KiB
Newer Older
  • Learn to ignore specific revisions
  • Eliot Berriot's avatar
    Eliot Berriot committed
    import logging
    import persisting_theory
    from django.apps import AppConfig
    
    
    logger = logging.getLogger("funkwhale.plugins")
    
    
    class PluginsRegistry(persisting_theory.Registry):
        look_into = "hooks"
    
        def prepare_name(self, data, name=None):
            return data.name
    
        def prepare_data(self, data):
            data.plugins_registry = self
            return data
    
        def dispatch_action(self, action_name, **kwargs):
            logger.debug("Dispatching plugin action %s", action_name)
            for plugin in self.values():
                try:
                    handler = plugin.hooked_actions[action_name]
                except KeyError:
                    continue
    
                logger.debug("Hook found for plugin %s", plugin.name)
                try:
                    handler(plugin=plugin, **kwargs)
                except Exception:
                    logger.exception(
                        "Hook for action %s from plugin %s failed. The plugin may be misconfigured.",
                        action_name,
                        plugin.name,
                    )
                else:
                    logger.info(
                        "Hook for action %s from plugin %s successful",
                        action_name,
                        plugin.name,
                    )
    
    
    registry = PluginsRegistry()
    
    
    class Plugin(AppConfig):
        _is_funkwhale_plugin = True
        is_initialized = False
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.config = {}
            self.hooked_actions = {}
    
        def get_config(self, config):
            """
            Called with config options extracted from env vars, if any specified
            Returns a transformed dict
            """
            return config
    
        def set_config(self, config):
            """
            Simply persist the given config on the plugin
            """
            self.config = config
    
        def initialize(self):
            pass
    
        def register_action(self, action_name, func):
            logger.debug(
                "Registered hook for action %s via plugin %s", action_name, self.name
            )
            self.hooked_actions[action_name] = func
    
    
    def init(registry, plugins):
        logger.debug("Initializing plugins...")
        for plugin in plugins:
            logger.info("Initializing plugin %s", plugin.name)
            try:
                config = plugin.get_config({})
            except Exception:
                logger.exception(
                    "Error while getting configuration, plugin %s disabled", plugin.name
                )
                continue
    
            try:
                plugin.set_config(config)
            except Exception:
                logger.exception(
                    "Error while setting configuration, plugin %s disabled", plugin.name
                )
                continue
    
            try:
                plugin.initialize()
            except Exception:
                logger.exception(
                    "Error while initializing, plugin %s disabled", plugin.name
                )
                continue
    
            plugin.is_initialized = True
    
        # initialization complete, now we can log the "hooks.py" file in each
        # plugin directory
        registry.autodiscover([p.name for p in plugins if p.is_initialized])