XEP-0313: Fix off-by-one-page RSM fetching

Add a "results" interface to mam_fin, and fix some things in RSM

Items just received were not taken into account because:
- RSM code is checking iq['mam_fin']['results'], results were at
  iq['mam']['results']
- RSM handler was run after checking the number
This commit is contained in:
mathieui 2021-03-09 19:15:27 +01:00
parent 4cdcc4d155
commit e329eadbed
3 changed files with 23 additions and 3 deletions

View file

@ -135,6 +135,9 @@ class ResultIterator(AsyncIterator):
not r[self.recv_interface]['rsm']['last']:
raise StopAsyncIteration
if self.post_cb:
self.post_cb(r)
if r[self.recv_interface]['rsm']['count'] and \
r[self.recv_interface]['rsm']['first_index']:
count = int(r[self.recv_interface]['rsm']['count'])
@ -147,9 +150,6 @@ class ResultIterator(AsyncIterator):
self.start = r[self.recv_interface]['rsm']['first']
else:
self.start = r[self.recv_interface]['rsm']['last']
if self.post_cb:
self.post_cb(r)
return r
except XMPPError:
raise StopAsyncIteration

View file

@ -112,6 +112,7 @@ class XEP_0313(BasePlugin):
results = cb_data['collector'].stop()
if result['type'] == 'result':
result['mam']['results'] = results
result['mam_fin']['results'] = results
if iterator:
return self.xmpp['xep_0059'].iterate(
@ -185,6 +186,7 @@ class XEP_0313(BasePlugin):
results = cb_data['collector'].stop()
if result['type'] == 'result':
result['mam']['results'] = results
result['mam_fin']['results'] = results
iterator = self.xmpp['xep_0059'].iterate(
iq, 'mam', 'results', amount=amount,

View file

@ -187,6 +187,24 @@ class Fin(ElementBase):
name = 'fin'
namespace = 'urn:xmpp:mam:2'
plugin_attrib = 'mam_fin'
interfaces = {'results'}
def setup(self, xml=None):
ElementBase.setup(self, xml)
self._results: List[Message] = []
# The results interface is meant only as an easy
# way to access the set of collected message responses
# from the query.
def get_results(self) -> List[Message]:
return self._results
def set_results(self, values: List[Message]):
self._results = values
def del_results(self):
self._results = []
class Result(ElementBase):