diff sat/plugins/plugin_xep_0060.py @ 3308:384283adcce1

plugins XEP-0059, XEP-0060, XEP-0277, XEP-0313: better serialisation: `data_format.serialise` is now used for `mbGet`, and RSM/MAM values are not transtyped to strings anymore. A serialised dict is now used, items are put in the `items` key. Comments handling has been refactored to use a list for the potentially multiple comments nodes. `rsm` data are now in a `rsm` key of the dict, and `mam` data are merged with other metadata.
author Goffi <goffi@goffi.org>
date Thu, 16 Jul 2020 09:07:20 +0200
parents 4c98f4972db5
children 77177b13ff54
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0060.py	Fri Jun 19 15:47:16 2020 +0200
+++ b/sat/plugins/plugin_xep_0060.py	Thu Jul 16 09:07:20 2020 +0200
@@ -717,16 +717,24 @@
                 "node": node,
                 "uri": self.getNodeURI(service_jid, node),
             }
+            if mam_response is not None:
+                # mam_response is a dict with "complete" and "stable" keys
+                # we can put them directly in metadata
+                metadata.update(mam_response)
             if rsm_request is not None and rsm_response is not None:
-                metadata.update(
-                    {
-                        "rsm_" + key: value
-                        for key, value in rsm_response.toDict().items()
-                    }
-                )
-            if mam_response is not None:
-                for key, value in mam_response.items():
-                    metadata["mam_" + key] = value
+                metadata['rsm'] = rsm_response.toDict()
+                if mam_response is None:
+                    index = rsm_response.index
+                    count = rsm_response.count
+                    if index is None or count is None:
+                        # we don't have enough information to know if the data is complete
+                        # or not
+                        metadata["complete"] = None
+                    else:
+                        # normally we have a strict equality here but XEP-0059 states
+                        # that index MAY be approximative, so just in caseā€¦
+                        metadata["complete"] = index + len(items) >= count
+
             return (items, metadata)
 
         d.addCallback(addMetadata)
@@ -1107,6 +1115,7 @@
         @param node(unicode): node
         @return (unicode): URI of the node
         """
+        # FIXME: deprecated, use sat.tools.common.uri instead
         assert service is not None
         # XXX: urllib.urlencode use "&" to separate value, while XMPP URL (cf. RFC 5122)
         #      use ";" as a separator. So if more than one value is used in query_data,
@@ -1127,66 +1136,40 @@
     ):
         return self.rt_sessions.getResults(session_id, on_success, on_error, profile)
 
-    def transItemsData(self, items_data, item_cb=lambda item: item.toXml(),
-            serialise=False):
+    def transItemsData(self, items_data, item_cb=lambda item: item.toXml()):
         """Helper method to transform result from [getItems]
 
         the items_data must be a tuple(list[domish.Element], dict[unicode, unicode])
-        as returned by [getItems]. metadata values are then casted to unicode and
-        each item is passed to items_cb then optionally serialised with
-            data_format.serialise.
+        as returned by [getItems].
         @param items_data(tuple): tuple returned by [getItems]
         @param item_cb(callable): method to transform each item
-        @param serialise(bool): if True do a data_format.serialise
-            after applying item_cb
         @return (tuple): a serialised form ready to go throught bridge
         """
         items, metadata = items_data
-        if serialise:
-            items = [data_format.serialise(item_cb(item)) for item in items]
-        else:
-            items = [item_cb(item) for item in items]
+        items = [item_cb(item) for item in items]
 
-        return (
-            items,
-            {key: str(value) for key, value in metadata.items()},
-        )
+        return (items, metadata)
 
-    def transItemsDataD(self, items_data, item_cb, serialise=False):
+    def transItemsDataD(self, items_data, item_cb):
         """Helper method to transform result from [getItems], deferred version
 
         the items_data must be a tuple(list[domish.Element], dict[unicode, unicode])
         as returned by [getItems]. metadata values are then casted to unicode and
-        each item is passed to items_cb then optionally serialised with
-            data_format.serialise.
+        each item is passed to items_cb.
         An errback is added to item_cb, and when it is fired the value is filtered from
             final items
         @param items_data(tuple): tuple returned by [getItems]
         @param item_cb(callable): method to transform each item (must return a deferred)
-        @param serialise(bool): if True do a data_format.serialise
-            after applying item_cb
-        @return (tuple): a deferred which fire a serialised form ready to go throught
-            bridge
+        @return (tuple): a deferred which fire a dict which can be serialised to go
+            throught bridge
         """
         items, metadata = items_data
 
         def eb(failure_):
-            log.warning(f"Error while serialising/parsing item: {failure_.value}")
+            log.warning(f"Error while parsing item: {failure_.value}")
 
         d = defer.gatherResults([item_cb(item).addErrback(eb) for item in items])
-
-        def finishSerialisation(parsed_items):
-            if serialise:
-                items = [data_format.serialise(i) for i in parsed_items if i is not None]
-            else:
-                items = [i for i in parsed_items if i is not None]
-
-            return (
-                items,
-                {key: str(value) for key, value in metadata.items()},
-            )
-
-        d.addCallback(finishSerialisation)
+        d.addCallback(lambda parsed_items: (parsed_items, metadata))
         return d
 
     def serDList(self, results, failure_result=None):