Mercurial > libervia-backend
diff libervia/backend/tools/trigger.py @ 4182:4dc00e848961
core (tools/trigger): new `add_with_check` method:
this method add a wrapper which will skip the trigger is the plugin is not available in
the session (e.g. a component which doesn't use the plugin).
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 09 Dec 2023 19:19:26 +0100 |
parents | 4b842c1fb686 |
children | 0d7bb4df2343 |
line wrap: on
line diff
--- a/libervia/backend/tools/trigger.py Sat Dec 09 19:17:34 2023 +0100 +++ b/libervia/backend/tools/trigger.py Sat Dec 09 19:19:26 2023 +0100 @@ -19,8 +19,11 @@ """Misc usefull classes""" +import inspect +from typing import Callable from libervia.backend.core.i18n import _ from libervia.backend.core.log import getLogger +from libervia.backend.core.core_types import SatXMPPEntity log = getLogger(__name__) @@ -49,7 +52,18 @@ def __init__(self): self.__triggers = {} - def add(self, point_name, callback, priority=0): + def is_available(self, args: list): + """Check if plugin used in a client context, and if it's available""" + if not args or not isinstance(args[0], SatXMPPEntity): + # we are not in the context of a client + return True + client = args[0] + if not client.is_component: + # plugins are always avaialble for normal clients + return True + + + def add(self, point_name, callback: Callable, priority=0): """Add a trigger to a point @param point_name: name of the point when the trigger should be run @@ -74,6 +88,43 @@ key=lambda trigger_tuple: trigger_tuple[0], reverse=True ) + def add_with_check( + self, + point_name: str, + plugin, + callback: Callable, + priority: int=0 + ) -> None: + """Like [Add], but check session before running the trigger + + This method is to be used for triggers which can run in components and are + expecting a ``client``: as all plugins are not run for component, a check will be + added before running the trigger, if the plugin is not valid for this component, + the trigger is ignored. ``client`` must be the first positional argument. + + @param point_name: name of the trigger point + @param plugin: instance of the plugin using this trigger. This is necessary to + check if the plugin is available in the session. + @param callback: method to call at the trigger point + @param priority: callback will be called in priority order, biggest first + """ + if inspect.iscoroutinefunction(callback): + async def async_wrapper(client: SatXMPPEntity, *args, **kwargs): + if client.is_component and plugin not in client.plugins: + log.debug(f"Ignoring {callback} as parent plugin is not available") + return True + else: + return await callback(client, *args, **kwargs) + self.add(point_name, async_wrapper, priority) + else: + def sync_wrapper(client: SatXMPPEntity, *args, **kwargs): + if client.is_component and plugin not in client.plugins: + log.debug(f"Ignoring {callback} as parent plugin is not available") + return True + else: + return callback(client, *args, **kwargs) + self.add(point_name, sync_wrapper, priority) + def remove(self, point_name, callback): """Remove a trigger from a point