tmp (wokkel/rsm): various improvments:
- restored original tmp.wokkel.pubsub.PubSubService._toResponse_items
- changed arguments order in RSMRequest.__init__ to have most common arguments first
- added __str__ methods
- better parsing/toElement
- better handling of optional elements/attributes (count/index)
- _toResponse_items handler RSM set elements without modifying original pubsub _toResponse_items
- renamed parse to fromElement for coherency
This commit is contained in:
parent
b5d2fda488
commit
9c6d0fecc4
2 changed files with 131 additions and 77 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
# <max/> 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 <item/> 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue