diff --git a/src/plugins/plugin_xep_0277.py b/src/plugins/plugin_xep_0277.py
index 9f13220e..464fd890 100755
--- a/src/plugins/plugin_xep_0277.py
+++ b/src/plugins/plugin_xep_0277.py
@@ -528,7 +528,6 @@ class XEP_0277(object):
ret = yield self._p.publish(service, node, [item], profile_key=profile)
defer.returnValue(ret)
-
## retract ##
def _mbRetract(self, service_jid_s, nodeIdentifier, itemIdentifier, profile_key):
@@ -680,8 +679,6 @@ class XEP_0277(object):
publishers[:] = [jid.JID(publisher) for publisher in publishers]
return publishers_type, publishers
-
-
# subscribe #
def _mbSubscribeToMany(self, publishers_type, publishers, profile_key):
diff --git a/src/tmp/wokkel/pubsub.py b/src/tmp/wokkel/pubsub.py
index 3a09f638..8b0f5db0 100755
--- a/src/tmp/wokkel/pubsub.py
+++ b/src/tmp/wokkel/pubsub.py
@@ -1408,12 +1408,8 @@ class PubSubService(XMPPHandler, IQHandlerMixin):
items["node"] = request.nodeIdentifier
for item in result:
- if isinstance(item, tuple):
- # XXX: see sat_pubsub.pgsql_storage.LeafNode.getItemsById return value
- item = item[0]
- if item.name == 'item':
- item.uri = NS_PUBSUB
- items.addChild(item)
+ item.uri = NS_PUBSUB
+ items.addChild(item)
return response
diff --git a/src/tmp/wokkel/rsm.py b/src/tmp/wokkel/rsm.py
index 6cc83451..93631039 100644
--- a/src/tmp/wokkel/rsm.py
+++ b/src/tmp/wokkel/rsm.py
@@ -45,7 +45,7 @@ class RSMNotFoundError(Exception):
"""
-class RSMRequest():
+class RSMRequest(object):
"""
A Result Set Management request.
@@ -62,28 +62,28 @@ class RSMRequest():
@itype before: C{unicode}
"""
- def __init__(self, max_=10, index=None, after=None, before=None):
- max_ = int(max_)
- assert max_ >= 0
- self.max = max_
+ def __init__(self, max_=10, after=None, before=None, index=None):
+ self.max = int(max_)
if index is not None:
assert after is None and before is None
index = int(index)
- assert index >= 0
self.index = index
if after is not None:
assert before is None
- assert isinstance(after, unicode)
+ assert isinstance(after, basestring)
self.after = after
if before is not None:
- assert isinstance(before, unicode)
+ assert isinstance(before, basestring)
self.before = before
+ def __str__(self):
+ return "RSM Request: max={0.max} after={0.after} before={0.before} index={0.index}".format(self)
+
@classmethod
- def parse(cls, element):
+ def fromElement(cls, element):
"""Parse the given request element.
@param element: request containing a set element.
@@ -97,17 +97,43 @@ class RSMRequest():
except StopIteration:
raise RSMNotFoundError()
- request = RSMRequest()
- for elt in set_elt.elements():
- if elt.name in ('before', 'after'):
- setattr(request, elt.name, ''.join(elt.children))
- elif elt.name in ('max', 'index'):
- setattr(request, elt.name, int(''.join(elt.children)))
+ try:
+ before_elt = set_elt.elements(NS_RSM, 'before').next()
+ except StopIteration:
+ before = None
+ else:
+ before = unicode(before_elt)
- if request.max is None:
+ try:
+ after_elt = set_elt.elements(NS_RSM, 'after').next()
+ except StopIteration:
+ after = None
+ else:
+ after = unicode(after_elt)
+
+ try:
+ max_elt = set_elt.elements(NS_RSM, 'max').next()
+ except StopIteration:
+ # FIXME: even if it doesn't make a lot of sense without it
+ # element is not mandatory in XEP-0059
raise RSMError("RSM request is missing its 'max' element")
+ else:
+ try:
+ max_ = int(unicode(max_elt))
+ except ValueError:
+ raise RSMError("bad value for 'max' element")
- return request
+ try:
+ index_elt = set_elt.elements(NS_RSM, 'index').next()
+ except StopIteration:
+ index = None
+ else:
+ try:
+ index = int(unicode(index_elt))
+ except ValueError:
+ raise RSMError("bad value for 'index' element")
+
+ return RSMRequest(max_, after, before, index)
def toElement(self):
"""
@@ -116,19 +142,19 @@ class RSMRequest():
@rtype: L{domish.Element}
"""
set_elt = domish.Element((NS_RSM, 'set'))
- set_elt.addElement('max').addContent(unicode(self.max))
+ set_elt.addElement('max', content=unicode(self.max))
if self.index is not None:
- set_elt.addElement('index').addContent(unicode(self.index))
+ set_elt.addElement('index', content=unicode(self.index))
if self.before is not None:
if self.before == '': # request the last page
set_elt.addElement('before')
else:
- set_elt.addElement('before').addContent(self.before)
+ set_elt.addElement('before', content=self.before)
if self.after is not None:
- set_elt.addElement('after').addContent(self.after)
+ set_elt.addElement('after', content=self.after)
return set_elt
@@ -150,38 +176,45 @@ class RSMRequest():
return set_elt
-class RSMResponse():
+class RSMResponse(object):
"""
A Result Set Management response.
- @ivar count: total number of items.
- @itype count: C{int}
-
- @ivar index: starting index of the returned page.
- @itype index: C{int}
-
@ivar first: ID of the first element of the returned page.
@itype first: C{unicode}
@ivar last: ID of the last element of the returned page.
@itype last: C{unicode}
+
+ @ivar index: starting index of the returned page.
+ @itype index: C{int}
+
+ @ivar count: total number of items.
+ @itype count: C{int}
+
"""
- def __init__(self, count=0, index=None, first=None, last=None):
- assert isinstance(count, int) and count >= 0
- self.count = count
- if index is not None:
- assert isinstance(index, int) and index >= 0
- assert isinstance(first, unicode)
- assert isinstance(last, unicode)
- else:
- assert first is None and last is None
- self.index = index
+ def __init__(self, first=None, last=None, index=None, count=None):
+ if first is None:
+ assert last is None and index is None
+ if last is None:
+ assert first is None
self.first = first
self.last = last
+ if count is not None:
+ self.count = int(count)
+ else:
+ self.count = None
+ if index is not None:
+ self.index = int(index)
+ else:
+ self.index = None
+
+ def __str__(self):
+ return "RSM Request: first={0.first} last={0.last} index={0.index} count={0.count}".format(self)
@classmethod
- def parse(cls, element):
+ def fromElement(cls, element):
"""Parse the given response element.
@param element: response element.
@@ -195,19 +228,43 @@ class RSMResponse():
except StopIteration:
raise RSMNotFoundError()
- response = RSMResponse()
- for elt in list(set_elt.elements()):
- if elt.name in ('first', 'last'):
- setattr(response, elt.name, ''.join(elt.children))
- if elt.name == 'first':
- response.index = int(elt.getAttribute("index"))
- elif elt.name == 'count':
- response.count = int(''.join(elt.children))
+ try:
+ first_elt = set_elt.elements(NS_RSM, 'first').next()
+ except StopIteration:
+ first = None
+ index = None
+ else:
+ first = unicode(first_elt)
+ try:
+ index = int(first_elt['index'])
+ except KeyError:
+ index = None
+ except ValueError:
+ raise RSMError("bad index in RSM response")
- if response.count is None:
- raise RSMError("RSM response is missing its 'count' element")
+ try:
+ last_elt = set_elt.elements(NS_RSM, 'last').next()
+ except StopIteration:
+ if first is not None:
+ raise RSMError("RSM response is missing its 'last' element")
+ else:
+ last = None
+ else:
+ if first is None:
+ raise RSMError("RSM response is missing its 'first' element")
+ last = unicode(last_elt)
- return response
+ try:
+ count_elt = set_elt.elements(NS_RSM, 'count').next()
+ except StopIteration:
+ count = None
+ else:
+ try:
+ count = int(unicode(count_elt))
+ except ValueError:
+ raise RSMError("invalid count in RSM response")
+
+ return RSMResponse(first, last, index, count)
def toElement(self):
"""
@@ -216,14 +273,15 @@ class RSMResponse():
@rtype: L{domish.Element}
"""
set_elt = domish.Element((NS_RSM, 'set'))
- set_elt.addElement('count').addContent(unicode(self.count))
+ if self.first is not None:
+ first_elt = set_elt.addElement('first', content=self.first)
+ if self.index is not None:
+ first_elt['index'] = unicode(self.index)
- if self.index is not None:
- first_elt = set_elt.addElement('first')
- first_elt.addContent(self.first)
- first_elt['index'] = unicode(self.index)
+ set_elt.addElement('last', content=self.last)
- set_elt.addElement('last').addContent(self.last)
+ if self.count is not None:
+ set_elt.addElement('count', content=unicode(self.count))
return set_elt
@@ -247,7 +305,7 @@ class RSMResponse():
@rtype: C{dict} binding C{unicode} to C{unicode}
"""
result = {}
- for attr in ('count', 'index', 'first', 'last'):
+ for attr in ('first', 'last', 'index', 'count'):
value = getattr(self, attr)
if value is not None:
result[attr] = unicode(value)
@@ -270,7 +328,7 @@ class PubSubRequest(pubsub.PubSubRequest):
def _parse_rsm(self, verbElement):
try:
- self.rsm = RSMRequest.parse(verbElement.parent)
+ self.rsm = RSMRequest.fromElement(verbElement.parent)
except RSMNotFoundError:
self.rsm = None
@@ -331,7 +389,7 @@ class PubSubClient(pubsub.PubSubClient):
if request.rsm:
try:
- response = RSMResponse.parse(iq.pubsub)
+ response = RSMResponse.fromElement(iq.pubsub)
if response is not None:
self._rsm_responses[ext_data['id']] = response
except RSMNotFoundError: # target pubsub server doesn't support RSM
@@ -364,15 +422,18 @@ class PubSubService(pubsub.PubSubService):
_request_class = PubSubRequest
- def _toResponse_items(self, result, resource, request):
- response = pubsub.PubSubService._toResponse_items(self, result,
- resource, request)
- for item in result:
- if isinstance(item, tuple):
- # XXX: see sat_pubsub.pgsql_storage.LeafNode.getItemsById return value
- item = item[0]
- if item.name == "set":
- response.addChild(item)
+ def _toResponse_items(self, elts, resource, request):
+ # default method only manage elements
+ # but we need to add RSM set element
+ rsm_elt = None
+ for idx, elt in enumerate(reversed(elts)):
+ if elt.name == "set" and elt.uri == NS_RSM:
+ rsm_elt = elts.pop(-1-idx)
break
+ response = pubsub.PubSubService._toResponse_items(self, elts,
+ resource, request)
+ if rsm_elt is not None:
+ response.addChild(rsm_elt)
+
return response