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.
This commit is contained in:
Goffi 2020-07-16 09:07:20 +02:00
commit e03eb5bfcc

View file

@ -717,16 +717,24 @@ class XEP_0060(object):
"node": node,
"uri": self.getNodeURI(service_jid, node),
}
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
# 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['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 @@ class XEP_0060(object):
@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 @@ class XEP_0060(object):
):
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):