Change the way we calculate new_limit in /publicRooms and add POST API

This commit is contained in:
Erik Johnston 2016-09-15 17:35:20 +01:00
parent de4f798f01
commit c33b25fd8d
2 changed files with 62 additions and 15 deletions

View File

@ -39,7 +39,8 @@ class RoomListHandler(BaseHandler):
super(RoomListHandler, self).__init__(hs) super(RoomListHandler, self).__init__(hs)
self.response_cache = ResponseCache(hs) self.response_cache = ResponseCache(hs)
def get_local_public_room_list(self, limit=None, since_token=None): def get_local_public_room_list(self, limit=None, since_token=None,
search_filter=None):
result = self.response_cache.get((limit, since_token)) result = self.response_cache.get((limit, since_token))
if not result: if not result:
result = self.response_cache.set( result = self.response_cache.set(
@ -49,7 +50,8 @@ class RoomListHandler(BaseHandler):
return result return result
@defer.inlineCallbacks @defer.inlineCallbacks
def _get_public_room_list(self, limit=None, since_token=None): def _get_public_room_list(self, limit=None, since_token=None,
search_filter=None):
if since_token and since_token != "END": if since_token and since_token != "END":
since_token = RoomListNextBatch.from_token(since_token) since_token = RoomListNextBatch.from_token(since_token)
else: else:
@ -115,22 +117,18 @@ class RoomListHandler(BaseHandler):
sorted_rooms = sorted_rooms[:since_token.current_limit] sorted_rooms = sorted_rooms[:since_token.current_limit]
sorted_rooms.reverse() sorted_rooms.reverse()
new_limit = None rooms_to_scan = sorted_rooms
if limit: if limit and not search_filter:
if sorted_rooms[limit:]: rooms_to_scan = sorted_rooms[:limit]
new_limit = limit
if since_token:
if since_token.direction_is_forward:
new_limit += since_token.current_limit
else:
new_limit = since_token.current_limit - new_limit
new_limit = max(0, new_limit)
sorted_rooms = sorted_rooms[:limit]
chunk = [] chunk = []
@defer.inlineCallbacks @defer.inlineCallbacks
def handle_room(room_id): def handle_room(room_id):
if limit and len(chunk) > limit:
# We've already got enough, so lets just drop it.
return
num_joined_users = rooms_to_num_joined[room_id] num_joined_users = rooms_to_num_joined[room_id]
if num_joined_users == 0: if num_joined_users == 0:
return return
@ -212,10 +210,29 @@ class RoomListHandler(BaseHandler):
chunk.append(result) chunk.append(result)
yield concurrently_execute(handle_room, sorted_rooms, 10) yield concurrently_execute(handle_room, rooms_to_scan, 10)
chunk.sort(key=lambda e: (-e["num_joined_members"], e["room_id"])) chunk.sort(key=lambda e: (-e["num_joined_members"], e["room_id"]))
new_limit = None
if chunk:
addition = 1
if since_token:
addition += since_token.current_limit
if not since_token or since_token.direction_is_forward:
last_room_id = chunk[-1]["room_id"]
else:
last_room_id = chunk[0]["room_id"]
addition *= -1
try:
new_limit = sorted_rooms.index(last_room_id) + addition
if new_limit >= len(sorted_rooms):
new_limit = None
except ValueError:
pass
results = { results = {
"chunk": chunk, "chunk": chunk,
} }
@ -253,7 +270,8 @@ class RoomListHandler(BaseHandler):
defer.returnValue(results) defer.returnValue(results)
@defer.inlineCallbacks @defer.inlineCallbacks
def get_remote_public_room_list(self, server_name, limit=None, since_token=None): def get_remote_public_room_list(self, server_name, limit=None, since_token=None,
search_filter=None):
res = yield self.hs.get_replication_layer().get_public_rooms( res = yield self.hs.get_replication_layer().get_public_rooms(
server_name, limit=limit, since_token=since_token, server_name, limit=limit, since_token=since_token,
) )

View File

@ -337,6 +337,35 @@ class PublicRoomListRestServlet(ClientV1RestServlet):
defer.returnValue((200, data)) defer.returnValue((200, data))
@defer.inlineCallbacks
def on_POST(self, request):
# FIXME
# yield self.auth.get_user_by_req(request)
server = parse_string(request, "server", default=None)
content = parse_json_object_from_request(request)
limit = int(content.get("limit", 100))
since_token = content.get("since", None)
search_filter = content.get("filter", None)
handler = self.hs.get_room_list_handler()
if server:
data = yield handler.get_remote_public_room_list(
server,
limit=limit,
since_token=since_token,
search_filter=search_filter,
)
else:
data = yield handler.get_local_public_room_list(
limit=limit,
since_token=since_token,
search_filter=search_filter,
)
defer.returnValue((200, data))
# TODO: Needs unit testing # TODO: Needs unit testing
class RoomMemberListRestServlet(ClientV1RestServlet): class RoomMemberListRestServlet(ClientV1RestServlet):