diff --git a/changelog.d/+timestamp-to-event.feature.md b/changelog.d/+timestamp-to-event.feature.md deleted file mode 100644 index c1f903968..000000000 --- a/changelog.d/+timestamp-to-event.feature.md +++ /dev/null @@ -1 +0,0 @@ -Added the `GET /_matrix/client/v1/rooms/{roomId}/timestamp_to_event` endpoint as per MSC3030, letting clients find the event closest to a given timestamp. Contributed by @eleboucher. diff --git a/src/api/client/room/mod.rs b/src/api/client/room/mod.rs index ba497afce..e249e18b6 100644 --- a/src/api/client/room/mod.rs +++ b/src/api/client/room/mod.rs @@ -3,11 +3,10 @@ mod event; mod initial_sync; mod summary; -mod timestamp_to_event; mod upgrade; pub(crate) use self::{ aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route, initial_sync::room_initial_sync_route, summary::get_room_summary, - timestamp_to_event::get_event_by_timestamp_route, upgrade::upgrade_room_route, + upgrade::upgrade_room_route, }; diff --git a/src/api/client/room/timestamp_to_event.rs b/src/api/client/room/timestamp_to_event.rs deleted file mode 100644 index 1ad09e40f..000000000 --- a/src/api/client/room/timestamp_to_event.rs +++ /dev/null @@ -1,62 +0,0 @@ -use axum::extract::State; -use conduwuit::{Err, Event, Result, err}; -use ruma::api::{Direction, client::room::get_event_by_timestamp}; - -use crate::Ruma; - -/// # `GET /_matrix/client/v1/rooms/{roomId}/timestamp_to_event` -/// -/// Gets the ID of the event closest to the given timestamp, in the direction -/// specified by `dir`. -pub(crate) async fn get_event_by_timestamp_route( - State(ref services): State, - body: Ruma, -) -> Result { - let sender_user = body.identity.expect_sender_user()?; - let room_id = &body.room_id; - - if !services - .rooms - .state_accessor - .user_can_see_state_events(sender_user, room_id) - .await - { - return Err!(Request(Forbidden("You don't have permission to view this room."))); - } - - let dir = match body.dir { - | Direction::Forward => "f", - | Direction::Backward => "b", - }; - - let not_found = || { - err!(Request(NotFound( - "Unable to find event from {} in direction {}", - body.ts.get(), - dir - ))) - }; - - let Some((_, event)) = services - .rooms - .timeline - .event_by_timestamp(room_id, body.ts, body.dir) - .await - else { - return Err(not_found()); - }; - - if !services - .rooms - .state_accessor - .user_can_see_event(sender_user, room_id, event.event_id()) - .await - { - return Err!(Request(Forbidden("You don't have permission to view this event."))); - } - - Ok(get_event_by_timestamp::v1::Response::new( - event.event_id().to_owned(), - event.origin_server_ts(), - )) -} diff --git a/src/api/router.rs b/src/api/router.rs index 58c6d188f..6b972043d 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -52,7 +52,6 @@ pub fn build(router: Router, state: State) -> Router { .ruma_route(&client::set_pushrule_actions_route) .ruma_route(&client::delete_pushrule_route) .ruma_route(&client::get_room_event_route) - .ruma_route(&client::get_event_by_timestamp_route) .ruma_route(&client::get_room_aliases_route) .ruma_route(&client::get_filter_route) .ruma_route(&client::create_filter_route) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index c8e20de06..715d52855 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -16,13 +16,13 @@ event::Event, pdu::{PduCount, PduEvent}, }, - utils::{MutexMap, MutexMapGuard, ReadyExt, future::TryExtExt, stream::TryIgnore}, + utils::{MutexMap, MutexMapGuard, future::TryExtExt, stream::TryIgnore}, warn, }; -use futures::{Future, Stream, StreamExt, TryStreamExt, pin_mut}; +use futures::{Future, Stream, TryStreamExt, pin_mut}; use ruma::{ - CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, RoomId, - api::Direction, events::room::encrypted::Relation, + CanonicalJsonObject, EventId, OwnedEventId, OwnedRoomId, RoomId, + events::room::encrypted::Relation, }; use serde::Deserialize; @@ -272,72 +272,4 @@ pub fn pdus<'a>( ) -> impl Stream> + Send + 'a { self.db.pdus(room_id, from.unwrap_or_else(PduCount::min)) } - - async fn pdu_at_or_after(&self, room_id: &RoomId, count: PduCount) -> Option { - let pdus = self - .pdus(room_id, Some(count.saturating_sub(1))) - .ignore_err() - .ready_filter(move |(at, _)| *at >= count); - - pin_mut!(pdus); - pdus.next().await - } - - async fn pdu_at_or_before(&self, room_id: &RoomId, count: PduCount) -> Option { - let pdus = self - .pdus_rev(room_id, Some(count.saturating_add(1))) - .ignore_err() - .ready_filter(move |(at, _)| *at <= count); - - pin_mut!(pdus); - pdus.next().await - } - - pub async fn event_by_timestamp( - &self, - room_id: &RoomId, - ts: MilliSecondsSinceUnixEpoch, - dir: Direction, - ) -> Option { - let first = self.pdu_at_or_after(room_id, PduCount::min()).await?.0; - let last = self.pdu_at_or_before(room_id, PduCount::max()).await?.0; - let mut low = first.into_signed(); - let mut high = last.into_signed(); - let mut result = None; - - match dir { - | Direction::Forward => - while low <= high { - let count = PduCount::from_signed(low.midpoint(high)); - let Some((at, pdu)) = self.pdu_at_or_after(room_id, count).await else { - high = count.into_signed().saturating_sub(1); - continue; - }; - - if pdu.origin_server_ts() >= ts { - result = Some((at, pdu)); - high = at.into_signed().saturating_sub(1); - } else { - low = at.into_signed().saturating_add(1); - } - }, - | Direction::Backward => - while low <= high { - let count = PduCount::from_signed(low.midpoint(high)); - let Some((at, pdu)) = self.pdu_at_or_before(room_id, count).await else { - low = count.into_signed().saturating_add(1); - continue; - }; - - if pdu.origin_server_ts() <= ts { - result = Some((at, pdu)); - low = at.into_signed().saturating_add(1); - } else { - high = at.into_signed().saturating_sub(1); - } - }, - } - - result - } }