async def on_GET( self, request: SynapseRequest, room_id: str, parent_id: str, relation_type: Optional[str] = None, event_type: Optional[str] = None, ) -> Tuple[int, JsonDict]: requester = await self.auth.get_user_by_req(request, allow_guest=True) await self.auth.check_user_in_room_or_world_readable( room_id, requester.user.to_string(), allow_departed_users=True, ) # This checks that a) the event exists and b) the user is allowed to # view it. event = await self.event_handler.get_event(requester.user, room_id, parent_id) if event is None: raise SynapseError(404, "Unknown parent event.") if relation_type not in (RelationTypes.ANNOTATION, None): raise SynapseError( 400, f"Relation type must be '{RelationTypes.ANNOTATION}'") limit = parse_integer(request, "limit", default=5) from_token_str = parse_string(request, "from") to_token_str = parse_string(request, "to") if event.internal_metadata.is_redacted(): # If the event is redacted, return an empty list of relations pagination_chunk = PaginationChunk(chunk=[]) else: # Return the relations from_token = None if from_token_str: from_token = AggregationPaginationToken.from_string( from_token_str) to_token = None if to_token_str: to_token = AggregationPaginationToken.from_string(to_token_str) pagination_chunk = await self.store.get_aggregation_groups_for_event( event_id=parent_id, room_id=room_id, event_type=event_type, limit=limit, from_token=from_token, to_token=to_token, ) return 200, pagination_chunk.to_dict()
def on_GET(self, request, room_id, parent_id, relation_type=None, event_type=None): requester = yield self.auth.get_user_by_req(request, allow_guest=True) yield self.auth.check_in_room_or_world_readable( room_id, requester.user.to_string()) # This checks that a) the event exists and b) the user is allowed to # view it. event = yield self.event_handler.get_event(requester.user, room_id, parent_id) if relation_type not in (RelationTypes.ANNOTATION, None): raise SynapseError(400, "Relation type must be 'annotation'") limit = parse_integer(request, "limit", default=5) from_token = parse_string(request, "from") to_token = parse_string(request, "to") if event.internal_metadata.is_redacted(): # If the event is redacted, return an empty list of relations pagination_chunk = PaginationChunk(chunk=[]) else: # Return the relations if from_token: from_token = AggregationPaginationToken.from_string(from_token) if to_token: to_token = AggregationPaginationToken.from_string(to_token) pagination_chunk = yield self.store.get_aggregation_groups_for_event( event_id=parent_id, event_type=event_type, limit=limit, from_token=from_token, to_token=to_token, ) defer.returnValue((200, pagination_chunk.to_dict()))
def _get_aggregation_groups_for_event_txn(txn): txn.execute(sql, where_args + [limit + 1]) next_batch = None events = [] for row in txn: events.append({"type": row[0], "key": row[1], "count": row[2]}) next_batch = AggregationPaginationToken(row[2], row[3]) if len(events) <= limit: next_batch = None return PaginationChunk(chunk=list(events[:limit]), next_batch=next_batch, prev_batch=from_token)
def _get_recent_references_for_event_txn(txn): txn.execute(sql, where_args + [limit + 1]) last_topo_id = None last_stream_id = None events = [] for row in txn: events.append({"event_id": row[0]}) last_topo_id = row[1] last_stream_id = row[2] next_batch = None if len(events) > limit and last_topo_id and last_stream_id: next_batch = RelationPaginationToken(last_topo_id, last_stream_id) return PaginationChunk( chunk=list(events[:limit]), next_batch=next_batch, prev_batch=from_token )
async def on_GET(self, request, room_id, parent_id, relation_type=None, event_type=None): requester = await self.auth.get_user_by_req(request, allow_guest=True) await self.auth.check_user_in_room_or_world_readable( room_id, requester.user.to_string(), allow_departed_users=True) # This gets the original event and checks that a) the event exists and # b) the user is allowed to view it. event = await self.event_handler.get_event(requester.user, room_id, parent_id) limit = parse_integer(request, "limit", default=5) from_token_str = parse_string(request, "from") to_token_str = parse_string(request, "to") if event.internal_metadata.is_redacted(): # If the event is redacted, return an empty list of relations pagination_chunk = PaginationChunk(chunk=[]) else: # Return the relations from_token = None if from_token_str: from_token = RelationPaginationToken.from_string( from_token_str) to_token = None if to_token_str: to_token = RelationPaginationToken.from_string(to_token_str) pagination_chunk = await self.store.get_relations_for_event( event_id=parent_id, relation_type=relation_type, event_type=event_type, limit=limit, from_token=from_token, to_token=to_token, ) events = await self.store.get_events_as_list( [c["event_id"] for c in pagination_chunk.chunk]) now = self.clock.time_msec() # We set bundle_aggregations to False when retrieving the original # event because we want the content before relations were applied to # it. original_event = await self._event_serializer.serialize_event( event, now, bundle_aggregations=False) # Similarly, we don't allow relations to be applied to relations, so we # return the original relations without any aggregations on top of them # here. events = await self._event_serializer.serialize_events( events, now, bundle_aggregations=False) return_value = pagination_chunk.to_dict() return_value["chunk"] = events return_value["original_event"] = original_event return 200, return_value
async def on_GET( self, request: SynapseRequest, room_id: str, parent_id: str, relation_type: Optional[str] = None, event_type: Optional[str] = None, ) -> Tuple[int, JsonDict]: requester = await self.auth.get_user_by_req(request, allow_guest=True) await self.auth.check_user_in_room_or_world_readable( room_id, requester.user.to_string(), allow_departed_users=True) # This gets the original event and checks that a) the event exists and # b) the user is allowed to view it. event = await self.event_handler.get_event(requester.user, room_id, parent_id) if event is None: raise SynapseError(404, "Unknown parent event.") limit = parse_integer(request, "limit", default=5) from_token_str = parse_string(request, "from") to_token_str = parse_string(request, "to") if event.internal_metadata.is_redacted(): # If the event is redacted, return an empty list of relations pagination_chunk = PaginationChunk(chunk=[]) else: # Return the relations from_token = None if from_token_str: from_token = RelationPaginationToken.from_string( from_token_str) to_token = None if to_token_str: to_token = RelationPaginationToken.from_string(to_token_str) pagination_chunk = await self.store.get_relations_for_event( event_id=parent_id, room_id=room_id, relation_type=relation_type, event_type=event_type, limit=limit, from_token=from_token, to_token=to_token, ) events = await self.store.get_events_as_list( [c["event_id"] for c in pagination_chunk.chunk]) now = self.clock.time_msec() # Do not bundle aggregations when retrieving the original event because # we want the content before relations are applied to it. original_event = self._event_serializer.serialize_event( event, now, bundle_aggregations=None) # The relations returned for the requested event do include their # bundled aggregations. aggregations = await self.store.get_bundled_aggregations( events, requester.user.to_string()) serialized_events = self._event_serializer.serialize_events( events, now, bundle_aggregations=aggregations) return_value = pagination_chunk.to_dict() return_value["chunk"] = serialized_events return_value["original_event"] = original_event return 200, return_value