diff sat/plugins/plugin_xep_0277.py @ 3513:753d151da886

XEP-0277: new preview/mbPreview method: This method does more or less the same thing as sending, but without actually sending the item, and parse the generated element just after. This way, the triggers are run, and a preview of the item can be made for the resulting microblog data.
author Goffi <goffi@goffi.org>
date Thu, 29 Apr 2021 15:49:59 +0200
parents 6132d363f0e9
children 02eec2a5b5f9
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0277.py	Fri Apr 23 10:08:58 2021 +0200
+++ b/sat/plugins/plugin_xep_0277.py	Thu Apr 29 15:49:59 2021 +0200
@@ -100,6 +100,14 @@
             async_=True,
         )
         host.bridge.addMethod(
+            "mbPreview",
+            ".plugin",
+            in_sign="ssss",
+            out_sign="s",
+            method=self._mbPreview,
+            async_=True,
+        )
+        host.bridge.addMethod(
             "mbRetract",
             ".plugin",
             in_sign="ssss",
@@ -651,7 +659,7 @@
 
         defer.returnValue(item_elt)
 
-    ## publish ##
+    ## publish/preview ##
 
     def getCommentsNode(self, item_id):
         """Generate comment node
@@ -803,27 +811,32 @@
                         client, comments_service, comments_node, comments_affiliations
                     )
 
+    def friendlyId(self, data):
+        """Generate a user friendly id from title or content"""
+        id_base = regex.urlFriendlyText(data.get('title') or data.get('content', ''))
+        return f"{id_base}-{token_urlsafe(3)}"
+
     def _mbSend(self, service, node, data, profile_key):
         service = jid.JID(service) if service else None
         node = node if node else NS_MICROBLOG
         client = self.host.getClient(profile_key)
         data = data_format.deserialise(data)
-        return self.send(client, data, service, node)
+        return defer.ensureDeferred(self.send(client, data, service, node))
 
-    def friendlyId(self, data):
-        """Generate a user friendly id from title or content"""
-        id_base = regex.urlFriendlyText(data.get('title') or data.get('content', ''))
-        return f"{id_base}-{token_urlsafe(3)}"
-
-    @defer.inlineCallbacks
-    def send(self, client, data, service=None, node=NS_MICROBLOG):
+    async def send(
+        self,
+        client: SatXMPPEntity,
+        data: dict,
+        service: Optional[jid.JID] = None,
+        node: Optional[str] = NS_MICROBLOG
+    ) -> None:
         """Send XEP-0277's microblog data
 
-        @param data(dict): microblog data (must include at least a "content" or a "title" key).
+        @param data: microblog data (must include at least a "content" or a "title" key).
             see http://wiki.goffi.org/wiki/Bridge_API_-_Microblogging/en for details
-        @param service(jid.JID, None): PubSub service where the microblog must be published
+        @param service: PubSub service where the microblog must be published
             None to publish on profile's PEP
-        @param node(unicode, None): PubSub node to use (defaut to microblog NS)
+        @param node: PubSub node to use (defaut to microblog NS)
             None is equivalend as using default value
         """
         # TODO: check that all data keys are used, this would avoid sending publicly a private message
@@ -839,12 +852,43 @@
                 item_id = str(shortuuid.uuid())
 
         try:
-            yield self._manageComments(client, data, service, node, item_id, access=None)
+            await self._manageComments(client, data, service, node, item_id, access=None)
         except error.StanzaError:
             log.warning("Can't create comments node for item {}".format(item_id))
-        item = yield self.data2entry(client, data, item_id, service, node)
-        ret = yield self._p.publish(client, service, node, [item])
-        defer.returnValue(ret)
+        item = await self.data2entry(client, data, item_id, service, node)
+        return await self._p.publish(client, service, node, [item])
+
+    def _mbPreview(self, service, node, data, profile_key):
+        service = jid.JID(service) if service else None
+        node = node if node else NS_MICROBLOG
+        client = self.host.getClient(profile_key)
+        data = data_format.deserialise(data)
+        d = defer.ensureDeferred(self.preview(client, data, service, node))
+        d.addCallback(data_format.serialise)
+        return d
+
+    async def preview(
+        self,
+        client: SatXMPPEntity,
+        data: dict,
+        service: Optional[jid.JID] = None,
+        node: Optional[str] = NS_MICROBLOG
+    ) -> dict:
+        """Preview microblog data without publishing them
+
+        params are the same as for [send]
+        @return: microblog data as would be retrieved from published item
+        """
+        if node is None:
+            node = NS_MICROBLOG
+
+        item_id = data.get("id", "")
+
+        # we have to serialise then deserialise to be sure that all triggers are called
+        item_elt = await self.data2entry(client, data, item_id, service, node)
+        item_elt.uri = pubsub.NS_PUBSUB
+        return await self.item2mbdata(client, item_elt, service, node)
+
 
     ## retract ##