diff sat/core/xmpp.py @ 3249:f16c96c7a91a

core (xmpp): helper method to launch a plugin method: the `p` client method can be used to launch a method for a plugin, with a default value if the plugin is not available (or an Exception to raise).
author Goffi <goffi@goffi.org>
date Fri, 03 Apr 2020 18:02:31 +0200
parents b10d207f95f9
children 6cf4bd6972c2
line wrap: on
line diff
--- a/sat/core/xmpp.py	Fri Apr 03 18:02:27 2020 +0200
+++ b/sat/core/xmpp.py	Fri Apr 03 18:02:31 2020 +0200
@@ -60,6 +60,28 @@
 ROSTER_VER_KEY = "@version@"
 
 
+class ClientPluginWrapper:
+    """Use a plugin with default value if plugin is missing"""
+
+    def __init__(self, client, plugin_name, missing):
+        self.client = client
+        self.plugin = client.host_app.plugins.get(plugin_name)
+        if self.plugin is None:
+            self.plugin_name = plugin_name
+        self.missing = missing
+
+    def __getattr__(self, attr):
+        if self.plugin is None:
+            missing = self.missing
+            if isinstance(missing, type) and issubclass(missing, Exception):
+                raise missing(f"plugin {self.plugin_name!r} is not available")
+            elif isinstance(missing, Exception):
+                raise missing
+            else:
+                return lambda *args, **kwargs: missing
+        return partial(getattr(self.plugin, attr), self.client)
+
+
 class SatXMPPEntity:
     """Common code for Client and Component"""
     # profile is added there when startConnection begins and removed when it is finished
@@ -736,6 +758,21 @@
                 log.warning(_("No message found"))
         return data
 
+    ## helper methods ##
+
+    def p(self, plugin_name, missing=exceptions.MissingModule):
+        """Get a plugin if available
+
+        @param plugin_name(str): name of the plugin
+        @param missing(object): value to return if plugin is missing
+            if it is a subclass of Exception, it will be raised with a helping str as
+            argument.
+        @return (object): requested plugin wrapper, or default value
+            The plugin wrapper will return the method with client set as first
+            positional argument
+        """
+        return ClientPluginWrapper(self, plugin_name, missing)
+
 
 @implementer(iwokkel.IDisco)
 class SatXMPPClient(SatXMPPEntity, wokkel_client.XMPPClient):