Skip to content

Commit

Permalink
Add /room/<room_id>/joined_members API
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
erikjohnston committed Dec 8, 2016
1 parent c45d8e9 commit 52d12ca
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
12 changes: 6 additions & 6 deletions synapse/push/bulk_push_rule_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ def action_for_event_by_user(self, event, context):
condition_cache = {}

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

filtered = filtered_by_user[uid]
if len(filtered) == 0:
Expand Down
19 changes: 19 additions & 0 deletions synapse/rest/client/v1/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,24 @@ def on_GET(self, request, room_id):
}))


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
class RoomMessageListRestServlet(ClientV1RestServlet):
PATTERNS = client_path_patterns("/rooms/(?P<room_id>[^/]*)/messages$")
Expand Down Expand Up @@ -743,6 +761,7 @@ def register_servlets(hs, http_server):
RoomStateEventRestServlet(hs).register(http_server)
RoomCreateRestServlet(hs).register(http_server)
RoomMemberListRestServlet(hs).register(http_server)
JoinedRoomMemberListRestServlet(hs).register(http_server)
RoomMessageListRestServlet(hs).register(http_server)
JoinRoomAliasServlet(hs).register(http_server)
RoomForgetRestServlet(hs).register(http_server)
Expand Down
16 changes: 13 additions & 3 deletions synapse/storage/roommember.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,19 +409,29 @@ def _get_joined_users_from_context(self, room_id, state_group, current_state_ids
table="room_memberships",
column="event_id",
iterable=member_event_ids,
retcols=['user_id'],
retcols=['user_id', 'display_name', 'avatar_url'],
keyvalues={
"membership": Membership.JOIN,
},
batch_size=500,
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.membership == Membership.JOIN:
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)

Expand Down

0 comments on commit 52d12ca

Please sign in to comment.