comparison sat/plugins/plugin_xep_0059.py @ 3592:ef144aaea2bb

plugin XEP-0059: new `getNextRequest` method to generate request to retrieve next page
author Goffi <goffi@goffi.org>
date Thu, 29 Jul 2021 21:30:32 +0200
parents be6d91572633
children 766729ac4146
comparison
equal deleted inserted replaced
3591:d830c11eeef3 3592:ef144aaea2bb
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 2
3 3 # Result Set Management (XEP-0059)
4 # SAT plugin for Result Set Management (XEP-0059)
5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
6 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org) 5 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org)
7 6
8 # This program is free software: you can redistribute it and/or modify 7 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as published by 8 # it under the terms of the GNU Affero General Public License as published by
16 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
17 16
18 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 19
20 from typing import Optional
21 from zope.interface import implementer
22 from twisted.words.protocols.jabber import xmlstream
23 from wokkel import disco
24 from wokkel import iwokkel
25 from wokkel import rsm
21 from sat.core.i18n import _ 26 from sat.core.i18n import _
22 from sat.core.constants import Const as C 27 from sat.core.constants import Const as C
23 from sat.core.log import getLogger 28 from sat.core.log import getLogger
24 29
30
25 log = getLogger(__name__) 31 log = getLogger(__name__)
26
27 from wokkel import disco
28 from wokkel import iwokkel
29 from wokkel import rsm
30
31 from twisted.words.protocols.jabber import xmlstream
32 from zope.interface import implementer
33 32
34 33
35 PLUGIN_INFO = { 34 PLUGIN_INFO = {
36 C.PI_NAME: "Result Set Management", 35 C.PI_NAME: "Result Set Management",
37 C.PI_IMPORT_NAME: "XEP-0059", 36 C.PI_IMPORT_NAME: "XEP-0059",
100 data["last"] = rsm_response.last 99 data["last"] = rsm_response.last
101 if rsm_response.index is not None: 100 if rsm_response.index is not None:
102 data["index"] = rsm_response.index 101 data["index"] = rsm_response.index
103 return data 102 return data
104 103
104 def getNextRequest(
105 self,
106 rsm_request: rsm.RSMRequest,
107 rsm_response: rsm.RSMResponse,
108 log_progress: bool = True,
109 ) -> Optional[rsm.RSMRequest]:
110 """Generate next request to paginate through all items
111
112 Page will be retrieved forward
113 @param rsm_request: last request used
114 @param rsm_response: response from the last request
115 @return: request to retrive next page, or None if we are at the end
116 or if pagination is not possible
117 """
118 if rsm_request.max == 0:
119 log.warning("Can't do pagination if max is 0")
120 return None
121 if rsm_response is None:
122 # may happen if result set it empty, or we are at the end
123 return None
124 if (
125 rsm_response.count is not None
126 and rsm_response.index is not None
127 ):
128 next_index = rsm_response.index + rsm_request.max
129 if next_index >= rsm_response.count:
130 # we have reached the last page
131 return None
132
133 if log_progress:
134 log.debug(
135 f"retrieving items {next_index} to "
136 f"{min(next_index+rsm_request.max, rsm_response.count)} on "
137 f"{rsm_response.count} ({next_index/rsm_response.count*100:.2f}%)"
138 )
139
140 if rsm_response.last is None:
141 log.warning("Can't do pagination, no \"last\" received")
142 return None
143
144 return rsm.RSMRequest(
145 max_=rsm_request.max,
146 after=rsm_response.last
147 )
148
105 149
106 @implementer(iwokkel.IDisco) 150 @implementer(iwokkel.IDisco)
107 class XEP_0059_handler(xmlstream.XMPPHandler): 151 class XEP_0059_handler(xmlstream.XMPPHandler):
108 152
109 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): 153 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):