# HG changeset patch # User Goffi # Date 1546792190 -3600 # Node ID 9a787881b824de295cbba2b50a170a543c8b9407 # Parent 40e5edd7ea11f2b6938bce50f40d37dc314396a8 implemented Order-By ProtoXEP (MAM + PubSub) diff -r 40e5edd7ea11 -r 9a787881b824 src/backend.py --- a/src/backend.py Thu Jan 03 20:31:03 2019 +0100 +++ b/src/backend.py Sun Jan 06 17:29:50 2019 +0100 @@ -77,6 +77,7 @@ from wokkel import rsm from wokkel import iwokkel from wokkel import pubsub +from wokkel.subprotocols import XMPPHandler from sat_pubsub import error from sat_pubsub import iidavoll @@ -1663,6 +1664,7 @@ ext_data['pep'] = request.delegated except AttributeError: pass + ext_data['order_by'] = request.orderBy or [] d = self.backend.getItems(request.nodeIdentifier, request.sender, request.recipient, @@ -1697,3 +1699,16 @@ components.registerAdapter(PubSubResourceFromBackend, iidavoll.IBackendService, iwokkel.IPubSubResource) + + + +class ExtraDiscoHandler(XMPPHandler): + implements(iwokkel.IDisco) + # see comment in twisted/plugins/pubsub.py + # FIXME: upstream must be fixed so we can use custom (non pubsub#) disco features + + def getDiscoInfo(self, requestor, service, nodeIdentifier=''): + return [disco.DiscoFeature(pubsub.NS_ORDER_BY)] + + def getDiscoItems(self, requestor, service, nodeIdentifier=''): + return [] diff -r 40e5edd7ea11 -r 9a787881b824 src/mam.py --- a/src/mam.py Thu Jan 03 20:31:03 2019 +0100 +++ b/src/mam.py Sun Jan 06 17:29:50 2019 +0100 @@ -85,6 +85,9 @@ else: ext_data['rsm'] = mam_request.rsm + if mam_request.orderBy: + ext_data['order_by'] = mam_request.orderBy + d = self.backend.getItemsData(mam_request.node, mam_request.sender, mam_request.recipient, None, None, ext_data) def make_message(elt): diff -r 40e5edd7ea11 -r 9a787881b824 src/pgsql_storage.py --- a/src/pgsql_storage.py Thu Jan 03 20:31:03 2019 +0100 +++ b/src/pgsql_storage.py Sun Jan 06 17:29:50 2019 +0100 @@ -834,6 +834,29 @@ nodeType = 'leaf' + def getOrderBy(self, ext_data, direction='DESC'): + """Return ORDER BY clause corresponding to Order By key in ext_data + + @param ext_data (dict): extra data as used in getItems + @param direction (unicode): ORDER BY direction (ASC or DESC) + @return (unicode): ORDER BY clause to use + """ + keys = ext_data.get('order_by') + if not keys: + return u'ORDER BY items.updated ' + direction + cols_statmnt = [] + for key in keys: + if key == 'creation': + column = 'items.item_id' # could work with items.created too + elif key == 'modification': + column = 'items.updated' + else: + log.msg(u"WARNING: Unknown order by key: {key}".format(key=key)) + column = 'items.updated' + cols_statmnt.append(column + u' ' + direction) + + return u"ORDER BY " + u",".join([col for col in cols_statmnt]) + def storeItems(self, item_data, publisher): return self.dbpool.runInteraction(self._storeItems, item_data, publisher) @@ -1031,7 +1054,7 @@ query.extend(query_filters) - return "ORDER BY items.updated DESC" + return self.getOrderBy(ext_data) def _getItems(self, cursor, authorized_groups, unrestricted, maxItems, ext_data, ids_only): self._checkNodeExists(cursor) @@ -1075,7 +1098,8 @@ # if we have maxItems (i.e. a limit), we need to reverse order # in a first query to get the right items query.insert(0,"SELECT * from (") - query.append("ORDER BY updated ASC LIMIT %s) as x") + query.append(self.getOrderBy(ext_data, direction='ASC')) + query.append("LIMIT %s) as x") args.append(maxItems) elif rsm.after: query.append("AND item_id<(SELECT item_id FROM items WHERE item=%s LIMIT 1)") diff -r 40e5edd7ea11 -r 9a787881b824 src/twisted/plugins/pubsub.py --- a/src/twisted/plugins/pubsub.py Thu Jan 03 20:31:03 2019 +0100 +++ b/src/twisted/plugins/pubsub.py Sun Jan 06 17:29:50 2019 +0100 @@ -69,7 +69,7 @@ from sat_pubsub import const from sat_pubsub import mam as pubsub_mam -from sat_pubsub.backend import BackendService +from sat_pubsub.backend import BackendService, ExtraDiscoHandler from sat_pubsub.schema import SchemaHandler from sat_pubsub.privilege import PrivilegesHandler from sat_pubsub.delegation import DelegationsHandler @@ -231,6 +231,13 @@ sh = SchemaHandler() sh.setHandlerParent(cs) + # wokkel.pubsub doesn't handle non pubsub# disco + # and we need to announce other feature, so this is a workaround + # to add them + # FIXME: propose a patch upstream to fix this situation + ed = ExtraDiscoHandler() + ed.setHandlerParent(cs) + # XXX: delegation must be instancied at the end, # because it does some MonkeyPatching on handlers dh = DelegationsHandler()