Add /room/<room_id>/joined_members API

This returns the currently joined members in the room with their display
names and avatar urls. This is more efficient than /members for large
rooms where you don't need the full events.
This commit is contained in:
Erik Johnston 2016-12-08 13:32:05 +00:00
parent c45d8e9ba2
commit 52d12ca782
3 changed files with 38 additions and 9 deletions

View file

@ -87,12 +87,12 @@ class BulkPushRuleEvaluator:
condition_cache = {} condition_cache = {}
for uid, rules in self.rules_by_user.items(): for uid, rules in self.rules_by_user.items():
display_name = None display_name = room_members.get(uid, {}).get("display_name", None)
member_ev_id = context.current_state_ids.get((EventTypes.Member, uid)) if not display_name:
if member_ev_id: # Handle the case where we are pushing a membership event to
member_ev = yield self.store.get_event(member_ev_id, allow_none=True) # that user, as they might not be already joined.
if member_ev: if event.type == EventTypes.Member and event.state_key == uid:
display_name = member_ev.content.get("displayname", None) display_name = event.content.get("displayname", None)
filtered = filtered_by_user[uid] filtered = filtered_by_user[uid]
if len(filtered) == 0: if len(filtered) == 0:

View file

@ -369,6 +369,24 @@ class RoomMemberListRestServlet(ClientV1RestServlet):
})) }))
class JoinedRoomMemberListRestServlet(ClientV1RestServlet):
PATTERNS = client_path_patterns("/rooms/(?P<room_id>[^/]*)/joined_members$")
def __init__(self, hs):
super(JoinedRoomMemberListRestServlet, self).__init__(hs)
self.state = hs.get_state_handler()
@defer.inlineCallbacks
def on_GET(self, request, room_id):
yield self.auth.get_user_by_req(request)
users_with_profile = yield self.state.get_current_user_in_room(room_id)
defer.returnValue((200, {
"joined": users_with_profile
}))
# TODO: Needs better unit testing # TODO: Needs better unit testing
class RoomMessageListRestServlet(ClientV1RestServlet): class RoomMessageListRestServlet(ClientV1RestServlet):
PATTERNS = client_path_patterns("/rooms/(?P<room_id>[^/]*)/messages$") PATTERNS = client_path_patterns("/rooms/(?P<room_id>[^/]*)/messages$")
@ -743,6 +761,7 @@ def register_servlets(hs, http_server):
RoomStateEventRestServlet(hs).register(http_server) RoomStateEventRestServlet(hs).register(http_server)
RoomCreateRestServlet(hs).register(http_server) RoomCreateRestServlet(hs).register(http_server)
RoomMemberListRestServlet(hs).register(http_server) RoomMemberListRestServlet(hs).register(http_server)
JoinedRoomMemberListRestServlet(hs).register(http_server)
RoomMessageListRestServlet(hs).register(http_server) RoomMessageListRestServlet(hs).register(http_server)
JoinRoomAliasServlet(hs).register(http_server) JoinRoomAliasServlet(hs).register(http_server)
RoomForgetRestServlet(hs).register(http_server) RoomForgetRestServlet(hs).register(http_server)

View file

@ -409,7 +409,7 @@ class RoomMemberStore(SQLBaseStore):
table="room_memberships", table="room_memberships",
column="event_id", column="event_id",
iterable=member_event_ids, iterable=member_event_ids,
retcols=['user_id'], retcols=['user_id', 'display_name', 'avatar_url'],
keyvalues={ keyvalues={
"membership": Membership.JOIN, "membership": Membership.JOIN,
}, },
@ -417,11 +417,21 @@ class RoomMemberStore(SQLBaseStore):
desc="_get_joined_users_from_context", desc="_get_joined_users_from_context",
) )
users_in_room = set(row["user_id"] for row in rows) users_in_room = {
row["user_id"]: {
"display_name": row["display_name"],
"avatar_url": row["avatar_url"],
}
for row in rows
}
if event is not None and event.type == EventTypes.Member: if event is not None and event.type == EventTypes.Member:
if event.membership == Membership.JOIN: if event.membership == Membership.JOIN:
if event.event_id in member_event_ids: if event.event_id in member_event_ids:
users_in_room.add(event.state_key) users_in_room[event.state_key] = {
"display_name": event.content.get("displayname", None),
"avatar_url": event.content.get("avatar_url", None),
}
defer.returnValue(users_in_room) defer.returnValue(users_in_room)