mirror of
				https://github.com/matrix-org/synapse.git
				synced 2025-11-04 10:11:05 +01:00 
			
		
		
		
	Send down device list change notif when member leaves/rejoins room
This commit is contained in:
		
							parent
							
								
									e2fcba038c
								
							
						
					
					
						commit
						53cc8ad35a
					
				@ -320,7 +320,7 @@ class DeviceHandler(BaseHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                # check if this member has changed since any of the extremities
 | 
					                # check if this member has changed since any of the extremities
 | 
				
			||||||
                # at the stream_ordering, and add them to the list if so.
 | 
					                # at the stream_ordering, and add them to the list if so.
 | 
				
			||||||
                for state_dict in prev_state_ids.values():
 | 
					                for state_dict in prev_state_ids.itervalues():
 | 
				
			||||||
                    prev_event_id = state_dict.get(key, None)
 | 
					                    prev_event_id = state_dict.get(key, None)
 | 
				
			||||||
                    if not prev_event_id or prev_event_id != event_id:
 | 
					                    if not prev_event_id or prev_event_id != event_id:
 | 
				
			||||||
                        possibly_changed.add(state_key)
 | 
					                        possibly_changed.add(state_key)
 | 
				
			||||||
 | 
				
			|||||||
@ -108,6 +108,16 @@ class InvitedSyncResult(collections.namedtuple("InvitedSyncResult", [
 | 
				
			|||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DeviceLists(collections.namedtuple("DeviceLists", [
 | 
				
			||||||
 | 
					    "changed",   # list of user_ids whose devices may have changed
 | 
				
			||||||
 | 
					    "left",      # list of user_ids whose devices we no longer track
 | 
				
			||||||
 | 
					])):
 | 
				
			||||||
 | 
					    __slots__ = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __nonzero__(self):
 | 
				
			||||||
 | 
					        return bool(self.changed or self.left)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SyncResult(collections.namedtuple("SyncResult", [
 | 
					class SyncResult(collections.namedtuple("SyncResult", [
 | 
				
			||||||
    "next_batch",  # Token for the next sync
 | 
					    "next_batch",  # Token for the next sync
 | 
				
			||||||
    "presence",  # List of presence events for the user.
 | 
					    "presence",  # List of presence events for the user.
 | 
				
			||||||
@ -535,7 +545,7 @@ class SyncHandler(object):
 | 
				
			|||||||
        res = yield self._generate_sync_entry_for_rooms(
 | 
					        res = yield self._generate_sync_entry_for_rooms(
 | 
				
			||||||
            sync_result_builder, account_data_by_room
 | 
					            sync_result_builder, account_data_by_room
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        newly_joined_rooms, newly_joined_users = res
 | 
					        newly_joined_rooms, newly_joined_users, _, newly_left_users = res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        block_all_presence_data = (
 | 
					        block_all_presence_data = (
 | 
				
			||||||
            since_token is None and
 | 
					            since_token is None and
 | 
				
			||||||
@ -549,7 +559,11 @@ class SyncHandler(object):
 | 
				
			|||||||
        yield self._generate_sync_entry_for_to_device(sync_result_builder)
 | 
					        yield self._generate_sync_entry_for_to_device(sync_result_builder)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        device_lists = yield self._generate_sync_entry_for_device_list(
 | 
					        device_lists = yield self._generate_sync_entry_for_device_list(
 | 
				
			||||||
            sync_result_builder
 | 
					            sync_result_builder,
 | 
				
			||||||
 | 
					            newly_joined_rooms=newly_joined_rooms,
 | 
				
			||||||
 | 
					            newly_joined_users=newly_joined_users,
 | 
				
			||||||
 | 
					            newly_left_rooms=[],
 | 
				
			||||||
 | 
					            newly_left_users=newly_left_users,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        device_id = sync_config.device_id
 | 
					        device_id = sync_config.device_id
 | 
				
			||||||
@ -574,7 +588,9 @@ class SyncHandler(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @measure_func("_generate_sync_entry_for_device_list")
 | 
					    @measure_func("_generate_sync_entry_for_device_list")
 | 
				
			||||||
    @defer.inlineCallbacks
 | 
					    @defer.inlineCallbacks
 | 
				
			||||||
    def _generate_sync_entry_for_device_list(self, sync_result_builder):
 | 
					    def _generate_sync_entry_for_device_list(self, sync_result_builder,
 | 
				
			||||||
 | 
					                                             newly_joined_rooms, newly_joined_users,
 | 
				
			||||||
 | 
					                                             newly_left_rooms, newly_left_users):
 | 
				
			||||||
        user_id = sync_result_builder.sync_config.user.to_string()
 | 
					        user_id = sync_result_builder.sync_config.user.to_string()
 | 
				
			||||||
        since_token = sync_result_builder.since_token
 | 
					        since_token = sync_result_builder.since_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -582,16 +598,32 @@ class SyncHandler(object):
 | 
				
			|||||||
            changed = yield self.store.get_user_whose_devices_changed(
 | 
					            changed = yield self.store.get_user_whose_devices_changed(
 | 
				
			||||||
                since_token.device_list_key
 | 
					                since_token.device_list_key
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            if not changed:
 | 
					
 | 
				
			||||||
                defer.returnValue([])
 | 
					            # TODO: Check that these users are actually new, i.e. either they
 | 
				
			||||||
 | 
					            # weren't in the previous sync *or* they left and rejoined.
 | 
				
			||||||
 | 
					            changed.update(newly_joined_users)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # TODO: Add the members from newly_*_rooms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if not changed and not newly_left_users:
 | 
				
			||||||
 | 
					                defer.returnValue(DeviceLists(
 | 
				
			||||||
 | 
					                    changed=[],
 | 
				
			||||||
 | 
					                    left=newly_left_users,
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            users_who_share_room = yield self.store.get_users_who_share_room_with_user(
 | 
					            users_who_share_room = yield self.store.get_users_who_share_room_with_user(
 | 
				
			||||||
                user_id
 | 
					                user_id
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            defer.returnValue(users_who_share_room & changed)
 | 
					            defer.returnValue(DeviceLists(
 | 
				
			||||||
 | 
					                changed=users_who_share_room & changed,
 | 
				
			||||||
 | 
					                left=set(newly_left_users) - users_who_share_room,
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            defer.returnValue([])
 | 
					            defer.returnValue(DeviceLists(
 | 
				
			||||||
 | 
					                changed=[],
 | 
				
			||||||
 | 
					                left=[],
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @defer.inlineCallbacks
 | 
					    @defer.inlineCallbacks
 | 
				
			||||||
    def _generate_sync_entry_for_to_device(self, sync_result_builder):
 | 
					    def _generate_sync_entry_for_to_device(self, sync_result_builder):
 | 
				
			||||||
@ -755,8 +787,8 @@ class SyncHandler(object):
 | 
				
			|||||||
            account_data_by_room(dict): Dictionary of per room account data
 | 
					            account_data_by_room(dict): Dictionary of per room account data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Returns:
 | 
					        Returns:
 | 
				
			||||||
            Deferred(tuple): Returns a 2-tuple of
 | 
					            Deferred(tuple): Returns a 4-tuple of
 | 
				
			||||||
            `(newly_joined_rooms, newly_joined_users)`
 | 
					            `(newly_joined_rooms, newly_joined_users, newly_left_rooms, newly_left_users)`
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        user_id = sync_result_builder.sync_config.user.to_string()
 | 
					        user_id = sync_result_builder.sync_config.user.to_string()
 | 
				
			||||||
        block_all_room_ephemeral = (
 | 
					        block_all_room_ephemeral = (
 | 
				
			||||||
@ -787,7 +819,7 @@ class SyncHandler(object):
 | 
				
			|||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    if not tags_by_room:
 | 
					                    if not tags_by_room:
 | 
				
			||||||
                        logger.debug("no-oping sync")
 | 
					                        logger.debug("no-oping sync")
 | 
				
			||||||
                        defer.returnValue(([], []))
 | 
					                        defer.returnValue(([], [], [], []))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ignored_account_data = yield self.store.get_global_account_data_by_type_for_user(
 | 
					        ignored_account_data = yield self.store.get_global_account_data_by_type_for_user(
 | 
				
			||||||
            "m.ignored_user_list", user_id=user_id,
 | 
					            "m.ignored_user_list", user_id=user_id,
 | 
				
			||||||
@ -828,17 +860,24 @@ class SyncHandler(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Now we want to get any newly joined users
 | 
					        # Now we want to get any newly joined users
 | 
				
			||||||
        newly_joined_users = set()
 | 
					        newly_joined_users = set()
 | 
				
			||||||
 | 
					        newly_left_users = set()
 | 
				
			||||||
        if since_token:
 | 
					        if since_token:
 | 
				
			||||||
            for joined_sync in sync_result_builder.joined:
 | 
					            for joined_sync in sync_result_builder.joined:
 | 
				
			||||||
                it = itertools.chain(
 | 
					                it = itertools.chain(
 | 
				
			||||||
                    joined_sync.timeline.events, joined_sync.state.values()
 | 
					                    joined_sync.timeline.events, joined_sync.state.itervalues()
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                for event in it:
 | 
					                for event in it:
 | 
				
			||||||
                    if event.type == EventTypes.Member:
 | 
					                    if event.type == EventTypes.Member:
 | 
				
			||||||
                        if event.membership == Membership.JOIN:
 | 
					                        if event.membership == Membership.JOIN:
 | 
				
			||||||
                            newly_joined_users.add(event.state_key)
 | 
					                            newly_joined_users.add(event.state_key)
 | 
				
			||||||
 | 
					                        else:
 | 
				
			||||||
 | 
					                            prev_content = event.unsigned.get("prev_content", {})
 | 
				
			||||||
 | 
					                            prev_membership = prev_content.get("membership", None)
 | 
				
			||||||
 | 
					                            if prev_membership == Membership.JOIN:
 | 
				
			||||||
 | 
					                                newly_left_users.add(event.state_key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        defer.returnValue((newly_joined_rooms, newly_joined_users))
 | 
					        newly_left_users -= newly_joined_users
 | 
				
			||||||
 | 
					        defer.returnValue((newly_joined_rooms, newly_joined_users, [], newly_left_users))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @defer.inlineCallbacks
 | 
					    @defer.inlineCallbacks
 | 
				
			||||||
    def _have_rooms_changed(self, sync_result_builder):
 | 
					    def _have_rooms_changed(self, sync_result_builder):
 | 
				
			||||||
@ -1259,6 +1298,7 @@ class SyncResultBuilder(object):
 | 
				
			|||||||
        self.invited = []
 | 
					        self.invited = []
 | 
				
			||||||
        self.archived = []
 | 
					        self.archived = []
 | 
				
			||||||
        self.device = []
 | 
					        self.device = []
 | 
				
			||||||
 | 
					        self.to_device = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RoomSyncResultBuilder(object):
 | 
					class RoomSyncResultBuilder(object):
 | 
				
			||||||
 | 
				
			|||||||
@ -189,7 +189,8 @@ class SyncRestServlet(RestServlet):
 | 
				
			|||||||
            "account_data": {"events": sync_result.account_data},
 | 
					            "account_data": {"events": sync_result.account_data},
 | 
				
			||||||
            "to_device": {"events": sync_result.to_device},
 | 
					            "to_device": {"events": sync_result.to_device},
 | 
				
			||||||
            "device_lists": {
 | 
					            "device_lists": {
 | 
				
			||||||
                "changed": list(sync_result.device_lists),
 | 
					                "changed": list(sync_result.device_lists.changed),
 | 
				
			||||||
 | 
					                "left": list(sync_result.device_lists.left),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "presence": SyncRestServlet.encode_presence(
 | 
					            "presence": SyncRestServlet.encode_presence(
 | 
				
			||||||
                sync_result.presence, time_now
 | 
					                sync_result.presence, time_now
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user