From 23cb550d00ca41eb0447e3e84b5e9e2ef1f88047 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Tue, 28 Apr 2020 19:56:34 +0200 Subject: [PATCH] forget rooms, load history --- src/client_server.rs | 59 ++++++++++++++++++++++++++++++++++++++------ src/data.rs | 39 +++++++++++++++++++++++++++++ src/main.rs | 2 ++ 3 files changed, 92 insertions(+), 8 deletions(-) diff --git a/src/client_server.rs b/src/client_server.rs index 873d3ec4..80bf61ce 100644 --- a/src/client_server.rs +++ b/src/client_server.rs @@ -13,9 +13,9 @@ use ruma_client_api::{ filter::{self, create_filter, get_filter}, keys::{get_keys, upload_keys}, membership::{ - get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, leave_room, + get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, forget_room, leave_room, }, - message::create_message_event, + message::{get_message_events, create_message_event}, presence::set_presence, profile::{ get_avatar_url, get_display_name, get_profile, set_avatar_url, set_display_name, @@ -222,10 +222,13 @@ pub fn get_capabilities_route( body: Ruma, ) -> MatrixResult { // TODO + //let mut available = BTreeMap::new(); + //available.insert("5".to_owned(), get_capabilities::RoomVersionStability::Unstable); + MatrixResult(Ok(get_capabilities::Response { capabilities: get_capabilities::Capabilities { change_password: None, - room_versions: None, + room_versions: None, //Some(get_capabilities::RoomVersionsCapability { default: "5".to_owned(), available }), custom_capabilities: BTreeMap::new(), }, })) @@ -708,6 +711,17 @@ pub fn leave_room_route( MatrixResult(Ok(leave_room::Response)) } +#[post("/_matrix/client/r0/rooms/<_room_id>/forget", data = "")] +pub fn forget_room_route( + data: State, + body: Ruma, + _room_id: String, +) -> MatrixResult { + let user_id = body.user_id.clone().expect("user is authenticated"); + data.room_forget(&body.room_id, &user_id); + MatrixResult(Ok(forget_room::Response)) +} + #[post("/_matrix/client/r0/rooms/<_room_id>/invite", data = "")] pub fn invite_user_route( data: State, @@ -903,7 +917,7 @@ pub fn sync_route( data: State, body: Ruma, ) -> MatrixResult { - std::thread::sleep(Duration::from_millis(200)); + std::thread::sleep(Duration::from_millis(300)); let next_batch = data.last_pdu_index().to_string(); let mut joined_rooms = BTreeMap::new(); @@ -915,7 +929,8 @@ pub fn sync_route( .unwrap_or(0); for room_id in joined_roomids { let pdus = data.pdus_since(&room_id, since); - let room_events = pdus.into_iter().map(|pdu| pdu.to_room_event()).collect(); + let room_events = pdus.into_iter().map(|pdu| pdu.to_room_event()).collect::>(); + let is_first_pdu = data.room_pdu_first(&room_id, since); let mut edus = data.roomlatests_since(&room_id, since); edus.extend_from_slice(&data.roomactives_in(&room_id)); @@ -933,8 +948,8 @@ pub fn sync_route( notification_count: None, }, timeline: sync_events::Timeline { - limited: Some(false), - prev_batch: Some("".to_owned()), + limited: None, + prev_batch: Some(since.to_string()), events: room_events, }, state: sync_events::State { events: Vec::new() }, @@ -957,7 +972,7 @@ pub fn sync_route( account_data: sync_events::AccountData { events: Vec::new() }, timeline: sync_events::Timeline { limited: Some(false), - prev_batch: Some("".to_owned()), + prev_batch: Some(next_batch.clone()), events: room_events, }, state: sync_events::State { events: Vec::new() }, @@ -995,6 +1010,34 @@ pub fn sync_route( })) } +#[get("/_matrix/client/r0/rooms/<_room_id>/messages", data = "")] +pub fn get_message_events_route( + data: State, + body: Ruma, + _room_id: String) -> MatrixResult { + if let get_message_events::Direction::Forward = body.dir {todo!();} + + if let Ok(from) = body + .from + .clone() + .parse() { + let pdus = data.pdus_until(&body.room_id, from); + let room_events = pdus.into_iter().map(|pdu| pdu.to_room_event()).collect::>(); + MatrixResult(Ok(get_message_events::Response { + start: body.from.clone(), + end: "".to_owned(), + chunk: room_events, + + })) + } else { + MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Invalid from.".to_owned(), + status_code: http::StatusCode::BAD_REQUEST, + })) + } +} + #[get("/_matrix/client/r0/voip/turnServer")] pub fn turn_server_route() -> MatrixResult { // TODO diff --git a/src/data.rs b/src/data.rs index 88facca3..6e09d073 100644 --- a/src/data.rs +++ b/src/data.rs @@ -338,6 +338,13 @@ impl Data { ); } + pub fn room_forget(&self, room_id: &RoomId, user_id: &UserId) { + self.db.userid_leftroomids.remove_value( + user_id.to_string().as_bytes(), + room_id.to_string().as_bytes().into(), + ); + } + pub fn room_invite(&self, sender: &UserId, room_id: &RoomId, user_id: &UserId) { self.pdu_append( room_id.clone(), @@ -375,6 +382,15 @@ impl Data { .collect() } + pub fn room_pdu_first(&self, room_id: &RoomId, pdu_index: u64) -> bool { + let mut pdu_id = vec![b'd']; + pdu_id.extend_from_slice(room_id.to_string().as_bytes()); + pdu_id.push(0xff); + pdu_id.extend_from_slice(&pdu_index.to_be_bytes()); + + self.db.pduid_pdu.get_lt(&pdu_id).unwrap().is_none() + } + pub fn pdu_get(&self, event_id: &EventId) -> Option { self.db .eventid_pduid @@ -577,6 +593,29 @@ impl Data { pdus } + pub fn pdus_until(&self, room_id: &RoomId, until: u64) -> Vec { + let mut pdus = Vec::new(); + + // Create the first part of the full pdu id + let mut prefix = vec![b'd']; + prefix.extend_from_slice(room_id.to_string().as_bytes()); + prefix.push(0xff); // Add delimiter so we don't find rooms starting with the same id + + let mut current = prefix.clone(); + current.extend_from_slice(&until.to_be_bytes()); + + while let Some((key, value)) = self.db.pduid_pdu.get_lt(¤t).unwrap() { + if key.starts_with(&prefix) { + current = key.to_vec(); + pdus.push(serde_json::from_slice(&value).expect("pdu in db is valid")); + } else { + break; + } + } + + pdus + } + pub fn roomlatest_update(&self, user_id: &UserId, room_id: &RoomId, event: EduEvent) { let mut prefix = room_id.to_string().as_bytes().to_vec(); prefix.push(0xff); diff --git a/src/main.rs b/src/main.rs index 324e23fa..13998023 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,6 +48,7 @@ fn setup_rocket(data: Data) -> rocket::Rocket { client_server::join_room_by_id_route, client_server::join_room_by_id_or_alias_route, client_server::leave_room_route, + client_server::forget_room_route, client_server::invite_user_route, client_server::get_public_rooms_filtered_route, client_server::search_users_route, @@ -57,6 +58,7 @@ fn setup_rocket(data: Data) -> rocket::Rocket { client_server::create_state_event_for_key_route, client_server::create_state_event_for_empty_key_route, client_server::sync_route, + client_server::get_message_events_route, client_server::turn_server_route, client_server::publicised_groups_route, client_server::options_route,