plugin XEP-0277: blog items data are now entirely serialised before going to bridge:
So far, and for historical reasons, blog items data where serialised using a unicode: unicode dict, which was causing trouble for many types of values (timestamps, booleans, lists). This patch changes it by serialising the whole items before going to bridge, and deserialising it when going back. This way, complex data can be used easily in items. This impact psEvent and serItemsData* methods which are renamed transItemsData* because there are not always serialising anymore (a new argument "serialise" allows to specify it). When editing a blog post in jp, metadata are now more easy to manipulate, specially lists like tags.
This commit is contained in:
parent
c89a771c06
commit
512ae0b91e
1 changed files with 188 additions and 184 deletions
|
|
@ -24,6 +24,7 @@ from sat.core.log import getLogger
|
|||
log = getLogger(__name__)
|
||||
from sat.core import exceptions
|
||||
from sat.tools import sat_defer
|
||||
from sat.tools.common import data_format
|
||||
|
||||
from twisted.words.protocols.jabber import jid, error
|
||||
from twisted.internet import reactor, defer
|
||||
|
|
@ -280,7 +281,7 @@ class XEP_0060(object):
|
|||
|
||||
# high level observer method
|
||||
host.bridge.addSignal(
|
||||
"psEvent", ".plugin", signature="ssssa{ss}s"
|
||||
"psEvent", ".plugin", signature="ssssss"
|
||||
) # args: category, service(jid), node, type (C.PS_ITEMS, C.PS_DELETE), data, profile
|
||||
|
||||
# low level observer method, used if service/node is in watching list (see psNodeWatch* methods)
|
||||
|
|
@ -568,7 +569,7 @@ class XEP_0060(object):
|
|||
extra.rsm_request,
|
||||
extra.extra,
|
||||
)
|
||||
d.addCallback(self.serItemsData)
|
||||
d.addCallback(self.transItemsData)
|
||||
return d
|
||||
|
||||
def getItems(self, client, service, node, max_items=None, item_ids=None, sub_id=None,
|
||||
|
|
@ -648,7 +649,7 @@ class XEP_0060(object):
|
|||
)
|
||||
|
||||
def doSubscribe(data):
|
||||
self.subscribe(service, node, profile_key=client.profile).addErrback(
|
||||
self.subscribe(client, service, node).addErrback(
|
||||
subscribeEb, service, node
|
||||
)
|
||||
return data
|
||||
|
|
@ -1075,32 +1076,46 @@ class XEP_0060(object):
|
|||
):
|
||||
return self.rt_sessions.getResults(session_id, on_success, on_error, profile)
|
||||
|
||||
def serItemsData(self, items_data, item_cb=lambda item: item.toXml()):
|
||||
"""Helper method to serialise result from [getItems]
|
||||
def transItemsData(self, items_data, item_cb=lambda item: item.toXml(),
|
||||
serialise=False):
|
||||
"""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
|
||||
each item is passed to items_cb then optionally serialised with
|
||||
data_format.serialise.
|
||||
@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]
|
||||
|
||||
return (
|
||||
[item_cb(item) for item in items],
|
||||
items,
|
||||
{key: unicode(value) for key, value in metadata.iteritems()},
|
||||
)
|
||||
|
||||
def serItemsDataD(self, items_data, item_cb):
|
||||
"""Helper method to serialise result from [getItems], deferred version
|
||||
def transItemsDataD(self, items_data, item_cb, serialise=False):
|
||||
"""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
|
||||
An errback is added to item_cb, and when it is fired the value is filtered from final items
|
||||
each item is passed to items_cb then optionally serialised with
|
||||
data_format.serialise.
|
||||
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)
|
||||
@return (tuple): a deferred which fire a serialised form ready to go throught bridge
|
||||
@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
|
||||
"""
|
||||
items, metadata = items_data
|
||||
|
||||
|
|
@ -1111,9 +1126,14 @@ class XEP_0060(object):
|
|||
|
||||
d = defer.gatherResults([item_cb(item).addErrback(eb) for item in items])
|
||||
|
||||
def finishSerialisation(serialised_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 (
|
||||
[item for item in serialised_items if item is not None],
|
||||
items,
|
||||
{key: unicode(value) for key, value in metadata.iteritems()},
|
||||
)
|
||||
|
||||
|
|
@ -1315,7 +1335,7 @@ class XEP_0060(object):
|
|||
profile = self.host.getClient(profile_key).profile
|
||||
d = self.rt_sessions.getResults(
|
||||
session_id,
|
||||
on_success=lambda result: ("", self.serItemsData(result)),
|
||||
on_success=lambda result: ("", self.transItemsData(result)),
|
||||
on_error=lambda failure: (unicode(failure.value) or UNSPECIFIED, ([], {})),
|
||||
profile=profile,
|
||||
)
|
||||
|
|
@ -1348,14 +1368,8 @@ class XEP_0060(object):
|
|||
profile_key,
|
||||
)
|
||||
|
||||
def getFromMany(
|
||||
self,
|
||||
node_data,
|
||||
max_item=None,
|
||||
rsm_request=None,
|
||||
extra=None,
|
||||
profile_key=C.PROF_KEY_NONE,
|
||||
):
|
||||
def getFromMany(self, node_data, max_item=None, rsm_request=None, extra=None,
|
||||
profile_key=C.PROF_KEY_NONE):
|
||||
"""Get items from many nodes at once
|
||||
|
||||
@param node_data (iterable[tuple]): iterable of tuple (service, node) where:
|
||||
|
|
|
|||
Loading…
Reference in a new issue