Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
4181:bc898879af34 | 4182:4dc00e848961 |
---|---|
17 # You should have received a copy of the GNU Affero General Public License | 17 # You should have received a copy of the GNU Affero General Public License |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 """Misc usefull classes""" | 20 """Misc usefull classes""" |
21 | 21 |
22 import inspect | |
23 from typing import Callable | |
22 from libervia.backend.core.i18n import _ | 24 from libervia.backend.core.i18n import _ |
23 from libervia.backend.core.log import getLogger | 25 from libervia.backend.core.log import getLogger |
26 from libervia.backend.core.core_types import SatXMPPEntity | |
24 | 27 |
25 log = getLogger(__name__) | 28 log = getLogger(__name__) |
26 | 29 |
27 | 30 |
28 class TriggerException(Exception): | 31 class TriggerException(Exception): |
47 MAX_PRIORITY = Number.POSITIVE_INFINITY | 50 MAX_PRIORITY = Number.POSITIVE_INFINITY |
48 | 51 |
49 def __init__(self): | 52 def __init__(self): |
50 self.__triggers = {} | 53 self.__triggers = {} |
51 | 54 |
52 def add(self, point_name, callback, priority=0): | 55 def is_available(self, args: list): |
56 """Check if plugin used in a client context, and if it's available""" | |
57 if not args or not isinstance(args[0], SatXMPPEntity): | |
58 # we are not in the context of a client | |
59 return True | |
60 client = args[0] | |
61 if not client.is_component: | |
62 # plugins are always avaialble for normal clients | |
63 return True | |
64 | |
65 | |
66 def add(self, point_name, callback: Callable, priority=0): | |
53 """Add a trigger to a point | 67 """Add a trigger to a point |
54 | 68 |
55 @param point_name: name of the point when the trigger should be run | 69 @param point_name: name of the point when the trigger should be run |
56 @param callback: method to call at the trigger point | 70 @param callback: method to call at the trigger point |
57 @param priority: callback will be called in priority order, biggest | 71 @param priority: callback will be called in priority order, biggest |
71 ) | 85 ) |
72 self.__triggers[point_name].append((priority, callback)) | 86 self.__triggers[point_name].append((priority, callback)) |
73 self.__triggers[point_name].sort( | 87 self.__triggers[point_name].sort( |
74 key=lambda trigger_tuple: trigger_tuple[0], reverse=True | 88 key=lambda trigger_tuple: trigger_tuple[0], reverse=True |
75 ) | 89 ) |
90 | |
91 def add_with_check( | |
92 self, | |
93 point_name: str, | |
94 plugin, | |
95 callback: Callable, | |
96 priority: int=0 | |
97 ) -> None: | |
98 """Like [Add], but check session before running the trigger | |
99 | |
100 This method is to be used for triggers which can run in components and are | |
101 expecting a ``client``: as all plugins are not run for component, a check will be | |
102 added before running the trigger, if the plugin is not valid for this component, | |
103 the trigger is ignored. ``client`` must be the first positional argument. | |
104 | |
105 @param point_name: name of the trigger point | |
106 @param plugin: instance of the plugin using this trigger. This is necessary to | |
107 check if the plugin is available in the session. | |
108 @param callback: method to call at the trigger point | |
109 @param priority: callback will be called in priority order, biggest first | |
110 """ | |
111 if inspect.iscoroutinefunction(callback): | |
112 async def async_wrapper(client: SatXMPPEntity, *args, **kwargs): | |
113 if client.is_component and plugin not in client.plugins: | |
114 log.debug(f"Ignoring {callback} as parent plugin is not available") | |
115 return True | |
116 else: | |
117 return await callback(client, *args, **kwargs) | |
118 self.add(point_name, async_wrapper, priority) | |
119 else: | |
120 def sync_wrapper(client: SatXMPPEntity, *args, **kwargs): | |
121 if client.is_component and plugin not in client.plugins: | |
122 log.debug(f"Ignoring {callback} as parent plugin is not available") | |
123 return True | |
124 else: | |
125 return callback(client, *args, **kwargs) | |
126 self.add(point_name, sync_wrapper, priority) | |
76 | 127 |
77 def remove(self, point_name, callback): | 128 def remove(self, point_name, callback): |
78 """Remove a trigger from a point | 129 """Remove a trigger from a point |
79 | 130 |
80 @param point_name: name of the point when the trigger should be run | 131 @param point_name: name of the point when the trigger should be run |