# HG changeset patch # User Goffi # Date 1627587032 -7200 # Node ID ef144aaea2bb8a6a44d37f781a71c457bd08987e # Parent d830c11eeef36271b0483ac9db675f39ff57d68e plugin XEP-0059: new `getNextRequest` method to generate request to retrieve next page diff -r d830c11eeef3 -r ef144aaea2bb sat/plugins/plugin_xep_0059.py --- a/sat/plugins/plugin_xep_0059.py Thu Jul 29 21:28:48 2021 +0200 +++ b/sat/plugins/plugin_xep_0059.py Thu Jul 29 21:30:32 2021 +0200 @@ -1,7 +1,6 @@ #!/usr/bin/env python3 - -# SAT plugin for Result Set Management (XEP-0059) +# Result Set Management (XEP-0059) # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org) @@ -18,19 +17,19 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from typing import Optional +from zope.interface import implementer +from twisted.words.protocols.jabber import xmlstream +from wokkel import disco +from wokkel import iwokkel +from wokkel import rsm from sat.core.i18n import _ from sat.core.constants import Const as C from sat.core.log import getLogger + log = getLogger(__name__) -from wokkel import disco -from wokkel import iwokkel -from wokkel import rsm - -from twisted.words.protocols.jabber import xmlstream -from zope.interface import implementer - PLUGIN_INFO = { C.PI_NAME: "Result Set Management", @@ -102,6 +101,51 @@ data["index"] = rsm_response.index return data + def getNextRequest( + self, + rsm_request: rsm.RSMRequest, + rsm_response: rsm.RSMResponse, + log_progress: bool = True, + ) -> Optional[rsm.RSMRequest]: + """Generate next request to paginate through all items + + Page will be retrieved forward + @param rsm_request: last request used + @param rsm_response: response from the last request + @return: request to retrive next page, or None if we are at the end + or if pagination is not possible + """ + if rsm_request.max == 0: + log.warning("Can't do pagination if max is 0") + return None + if rsm_response is None: + # may happen if result set it empty, or we are at the end + return None + if ( + rsm_response.count is not None + and rsm_response.index is not None + ): + next_index = rsm_response.index + rsm_request.max + if next_index >= rsm_response.count: + # we have reached the last page + return None + + if log_progress: + log.debug( + f"retrieving items {next_index} to " + f"{min(next_index+rsm_request.max, rsm_response.count)} on " + f"{rsm_response.count} ({next_index/rsm_response.count*100:.2f}%)" + ) + + if rsm_response.last is None: + log.warning("Can't do pagination, no \"last\" received") + return None + + return rsm.RSMRequest( + max_=rsm_request.max, + after=rsm_response.last + ) + @implementer(iwokkel.IDisco) class XEP_0059_handler(xmlstream.XMPPHandler):