Ejemplo n.º 1
0
 async def get_receipts() -> List[JsonDict]:
     receipts = await self.store.get_linearized_receipts_for_room(
         room_id, to_key=now_token.receipt_key)
     if not receipts:
         return []
     if self.hs.config.experimental.msc2285_enabled:
         receipts = ReceiptEventSource.filter_out_private_receipts(
             receipts, user_id)
     return receipts
Ejemplo n.º 2
0
    async def _snapshot_all_rooms(
        self,
        user_id: str,
        pagin_config: PaginationConfig,
        as_client_event: bool = True,
        include_archived: bool = False,
    ) -> JsonDict:

        memberships = [Membership.INVITE, Membership.JOIN]
        if include_archived:
            memberships.append(Membership.LEAVE)

        room_list = await self.store.get_rooms_for_local_user_where_membership_is(
            user_id=user_id, membership_list=memberships)

        user = UserID.from_string(user_id)

        rooms_ret = []

        now_token = self.hs.get_event_sources().get_current_token()

        presence_stream = self.hs.get_event_sources().sources.presence
        presence, _ = await presence_stream.get_new_events(
            user, from_key=None, include_offline=False)

        joined_rooms = [
            r.room_id for r in room_list if r.membership == Membership.JOIN
        ]
        receipt = await self.store.get_linearized_receipts_for_rooms(
            joined_rooms,
            to_key=int(now_token.receipt_key),
        )
        if self.hs.config.experimental.msc2285_enabled:
            receipt = ReceiptEventSource.filter_out_private_receipts(
                receipt, user_id)

        tags_by_room = await self.store.get_tags_for_user(user_id)

        account_data, account_data_by_room = await self.store.get_account_data_for_user(
            user_id)

        public_room_ids = await self.store.get_public_room_ids()

        if pagin_config.limit is not None:
            limit = pagin_config.limit
        else:
            limit = 10

        serializer_options = SerializeEventConfig(
            as_client_event=as_client_event)

        async def handle_room(event: RoomsForUser) -> None:
            d: JsonDict = {
                "room_id":
                event.room_id,
                "membership":
                event.membership,
                "visibility":
                ("public" if event.room_id in public_room_ids else "private"),
            }

            if event.membership == Membership.INVITE:
                time_now = self.clock.time_msec()
                d["inviter"] = event.sender

                invite_event = await self.store.get_event(event.event_id)
                d["invite"] = self._event_serializer.serialize_event(
                    invite_event,
                    time_now,
                    config=serializer_options,
                )

            rooms_ret.append(d)

            if event.membership not in (Membership.JOIN, Membership.LEAVE):
                return

            try:
                if event.membership == Membership.JOIN:
                    room_end_token = now_token.room_key
                    deferred_room_state = run_in_background(
                        self._state_storage_controller.get_current_state,
                        event.room_id)
                elif event.membership == Membership.LEAVE:
                    room_end_token = RoomStreamToken(
                        None,
                        event.stream_ordering,
                    )
                    deferred_room_state = run_in_background(
                        self._state_storage_controller.get_state_for_events,
                        [event.event_id],
                    ).addCallback(lambda states: cast(StateMap[EventBase],
                                                      states[event.event_id]))

                (messages,
                 token), current_state = await make_deferred_yieldable(
                     gather_results((
                         run_in_background(
                             self.store.get_recent_events_for_room,
                             event.room_id,
                             limit=limit,
                             end_token=room_end_token,
                         ),
                         deferred_room_state,
                     ))).addErrback(unwrapFirstError)

                messages = await filter_events_for_client(
                    self._storage_controllers, user_id, messages)

                start_token = now_token.copy_and_replace(
                    StreamKeyType.ROOM, token)
                end_token = now_token.copy_and_replace(StreamKeyType.ROOM,
                                                       room_end_token)
                time_now = self.clock.time_msec()

                d["messages"] = {
                    "chunk": (self._event_serializer.serialize_events(
                        messages,
                        time_now=time_now,
                        config=serializer_options,
                    )),
                    "start":
                    await start_token.to_string(self.store),
                    "end":
                    await end_token.to_string(self.store),
                }

                d["state"] = self._event_serializer.serialize_events(
                    current_state.values(),
                    time_now=time_now,
                    config=serializer_options,
                )

                account_data_events = []
                tags = tags_by_room.get(event.room_id)
                if tags:
                    account_data_events.append({
                        "type": "m.tag",
                        "content": {
                            "tags": tags
                        }
                    })

                account_data = account_data_by_room.get(event.room_id, {})
                for account_data_type, content in account_data.items():
                    account_data_events.append({
                        "type": account_data_type,
                        "content": content
                    })

                d["account_data"] = account_data_events
            except Exception:
                logger.exception("Failed to get snapshot")

        await concurrently_execute(handle_room, room_list, 10)

        account_data_events = []
        for account_data_type, content in account_data.items():
            account_data_events.append({
                "type": account_data_type,
                "content": content
            })

        now = self.clock.time_msec()

        ret = {
            "rooms":
            rooms_ret,
            "presence": [{
                "type": EduTypes.PRESENCE,
                "content": format_user_presence_state(event, now),
            } for event in presence],
            "account_data":
            account_data_events,
            "receipts":
            receipt,
            "end":
            await now_token.to_string(self.store),
        }

        return ret