feat: presence updates

next
timokoesters 2020-05-09 21:47:09 +02:00
parent 551308e9a8
commit ee0d6940bd
No known key found for this signature in database
GPG Key ID: 356E705610F626D5
5 changed files with 293 additions and 193 deletions

View File

@ -12,7 +12,6 @@ use ruma_client_api::{
account::{get_username_availability, register}, account::{get_username_availability, register},
alias::get_alias, alias::get_alias,
capabilities::get_capabilities, capabilities::get_capabilities,
to_device::send_event_to_device,
config::{get_global_account_data, set_global_account_data}, config::{get_global_account_data, set_global_account_data},
directory::{self, get_public_rooms_filtered}, directory::{self, get_public_rooms_filtered},
filter::{self, create_filter, get_filter}, filter::{self, create_filter, get_filter},
@ -34,13 +33,14 @@ use ruma_client_api::{
state::{create_state_event_for_empty_key, create_state_event_for_key}, state::{create_state_event_for_empty_key, create_state_event_for_key},
sync::sync_events, sync::sync_events,
thirdparty::get_protocols, thirdparty::get_protocols,
to_device::send_event_to_device,
typing::create_typing_event, typing::create_typing_event,
uiaa::{AuthFlow, UiaaInfo, UiaaResponse}, uiaa::{AuthFlow, UiaaInfo, UiaaResponse},
user_directory::search_users, user_directory::search_users,
}, },
unversioned::get_supported_versions, unversioned::get_supported_versions,
}; };
use ruma_events::{collections::only::Event as EduEvent, EventType}; use ruma_events::{collections::only::Event as EduEvent, EventJson, EventType};
use ruma_identifiers::{RoomId, UserId}; use ruma_identifiers::{RoomId, UserId};
use serde_json::{json, value::RawValue}; use serde_json::{json, value::RawValue};
@ -165,45 +165,45 @@ pub fn register_route(
let token = utils::random_string(TOKEN_LENGTH); let token = utils::random_string(TOKEN_LENGTH);
// Add device // Add device
db db.users
.users
.create_device(&user_id, &device_id, &token) .create_device(&user_id, &device_id, &token)
.unwrap(); .unwrap();
// Initial data // Initial data
db.account_data.update( db.account_data
None, .update(
&user_id, None,
EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent { &user_id,
content: ruma_events::push_rules::PushRulesEventContent { EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent {
global: ruma_events::push_rules::Ruleset { content: ruma_events::push_rules::PushRulesEventContent {
content: vec![], global: ruma_events::push_rules::Ruleset {
override_rules: vec![], content: vec![],
room: vec![], override_rules: vec![],
sender: vec![], room: vec![],
underride: vec![ruma_events::push_rules::ConditionalPushRule { sender: vec![],
actions: vec![ underride: vec![ruma_events::push_rules::ConditionalPushRule {
ruma_events::push_rules::Action::Notify, actions: vec![
ruma_events::push_rules::Action::SetTweak( ruma_events::push_rules::Action::Notify,
ruma_common::push::Tweak::Highlight(false), ruma_events::push_rules::Action::SetTweak(
), ruma_common::push::Tweak::Highlight(false),
], ),
default: true, ],
enabled: true, default: true,
rule_id: ".m.rule.message".to_owned(), enabled: true,
conditions: vec![ruma_events::push_rules::PushCondition::EventMatch( rule_id: ".m.rule.message".to_owned(),
ruma_events::push_rules::EventMatchCondition { conditions: vec![ruma_events::push_rules::PushCondition::EventMatch(
key: "type".to_owned(), ruma_events::push_rules::EventMatchCondition {
pattern: "m.room.message".to_owned(), key: "type".to_owned(),
}, pattern: "m.room.message".to_owned(),
)], },
}], )],
}],
},
}, },
}, }),
}), &db.globals,
&db.globals, )
) .unwrap();
.unwrap();
MatrixResult(Ok(register::Response { MatrixResult(Ok(register::Response {
access_token: Some(token), access_token: Some(token),
@ -220,7 +220,10 @@ pub fn get_login_route() -> MatrixResult<get_login_types::Response> {
} }
#[post("/_matrix/client/r0/login", data = "<body>")] #[post("/_matrix/client/r0/login", data = "<body>")]
pub fn login_route(db: State<'_, Database>, body: Ruma<login::Request>) -> MatrixResult<login::Response> { pub fn login_route(
db: State<'_, Database>,
body: Ruma<login::Request>,
) -> MatrixResult<login::Response> {
// Validate login method // Validate login method
let user_id = let user_id =
if let (login::UserInfo::MatrixId(mut username), login::LoginInfo::Password { password }) = if let (login::UserInfo::MatrixId(mut username), login::LoginInfo::Password { password }) =
@ -280,8 +283,7 @@ pub fn login_route(db: State<'_, Database>, body: Ruma<login::Request>) -> Matri
let token = utils::random_string(TOKEN_LENGTH); let token = utils::random_string(TOKEN_LENGTH);
// Add device // Add device
db db.users
.users
.create_device(&user_id, &device_id, &token) .create_device(&user_id, &device_id, &token)
.unwrap(); .unwrap();
@ -318,7 +320,7 @@ pub fn get_pushrules_all_route() -> MatrixResult<get_pushrules_all::Response> {
vec![push::PushRule { vec![push::PushRule {
actions: vec![ actions: vec![
push::Action::Notify, push::Action::Notify,
push::Action::SetTweak(ruma_common::push::Tweak::Highlight(false)) push::Action::SetTweak(ruma_common::push::Tweak::Highlight(false)),
], ],
default: true, default: true,
enabled: true, enabled: true,
@ -346,39 +348,40 @@ pub fn set_pushrule_route(
) -> MatrixResult<set_pushrule::Response> { ) -> MatrixResult<set_pushrule::Response> {
// TODO // TODO
let user_id = body.user_id.clone().expect("user is authenticated"); let user_id = body.user_id.clone().expect("user is authenticated");
db.account_data.update( db.account_data
None, .update(
&user_id, None,
EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent { &user_id,
content: ruma_events::push_rules::PushRulesEventContent { EduEvent::PushRules(ruma_events::push_rules::PushRulesEvent {
global: ruma_events::push_rules::Ruleset { content: ruma_events::push_rules::PushRulesEventContent {
content: vec![], global: ruma_events::push_rules::Ruleset {
override_rules: vec![], content: vec![],
room: vec![], override_rules: vec![],
sender: vec![], room: vec![],
underride: vec![ruma_events::push_rules::ConditionalPushRule { sender: vec![],
actions: vec![ underride: vec![ruma_events::push_rules::ConditionalPushRule {
ruma_events::push_rules::Action::Notify, actions: vec![
ruma_events::push_rules::Action::SetTweak( ruma_events::push_rules::Action::Notify,
ruma_common::push::Tweak::Highlight(false), ruma_events::push_rules::Action::SetTweak(
), ruma_common::push::Tweak::Highlight(false),
], ),
default: true, ],
enabled: true, default: true,
rule_id: ".m.rule.message".to_owned(), enabled: true,
conditions: vec![ruma_events::push_rules::PushCondition::EventMatch( rule_id: ".m.rule.message".to_owned(),
ruma_events::push_rules::EventMatchCondition { conditions: vec![ruma_events::push_rules::PushCondition::EventMatch(
key: "type".to_owned(), ruma_events::push_rules::EventMatchCondition {
pattern: "m.room.message".to_owned(), key: "type".to_owned(),
}, pattern: "m.room.message".to_owned(),
)], },
}], )],
}],
},
}, },
}, }),
}), &db.globals,
&db.globals )
) .unwrap();
.unwrap();
MatrixResult(Ok(set_pushrule::Response)) MatrixResult(Ok(set_pushrule::Response))
} }
@ -393,9 +396,7 @@ pub fn set_pushrule_enabled_route(
MatrixResult(Ok(set_pushrule_enabled::Response)) MatrixResult(Ok(set_pushrule_enabled::Response))
} }
#[get( #[get("/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>")]
"/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>",
)]
pub fn get_filter_route( pub fn get_filter_route(
_user_id: String, _user_id: String,
_filter_id: String, _filter_id: String,
@ -413,18 +414,14 @@ pub fn get_filter_route(
} }
#[post("/_matrix/client/r0/user/<_user_id>/filter")] #[post("/_matrix/client/r0/user/<_user_id>/filter")]
pub fn create_filter_route( pub fn create_filter_route(_user_id: String) -> MatrixResult<create_filter::Response> {
_user_id: String,
) -> MatrixResult<create_filter::Response> {
// TODO // TODO
MatrixResult(Ok(create_filter::Response { MatrixResult(Ok(create_filter::Response {
filter_id: utils::random_string(10), filter_id: utils::random_string(10),
})) }))
} }
#[put( #[put("/_matrix/client/r0/user/<_user_id>/account_data/<_type>")]
"/_matrix/client/r0/user/<_user_id>/account_data/<_type>",
)]
pub fn set_global_account_data_route( pub fn set_global_account_data_route(
_user_id: String, _user_id: String,
_type: String, _type: String,
@ -432,9 +429,7 @@ pub fn set_global_account_data_route(
MatrixResult(Ok(set_global_account_data::Response)) MatrixResult(Ok(set_global_account_data::Response))
} }
#[get( #[get("/_matrix/client/r0/user/<_user_id>/account_data/<_type>")]
"/_matrix/client/r0/user/<_user_id>/account_data/<_type>",
)]
pub fn get_global_account_data_route( pub fn get_global_account_data_route(
_user_id: String, _user_id: String,
_type: String, _type: String,
@ -460,25 +455,44 @@ pub fn set_displayname_route(
if displayname == "" { if displayname == "" {
db.users.set_displayname(&user_id, None).unwrap(); db.users.set_displayname(&user_id, None).unwrap();
} else { } else {
db db.users
.users
.set_displayname(&user_id, Some(displayname.clone())) .set_displayname(&user_id, Some(displayname.clone()))
.unwrap(); .unwrap();
} }
// Send a new membership event into all joined rooms // Send a new membership event into all joined rooms
for room_id in db.rooms.rooms_joined(&user_id) { for room_id in db.rooms.rooms_joined(&user_id) {
db.rooms.append_pdu( db.rooms
room_id.unwrap(), .append_pdu(
user_id.clone(), room_id.unwrap(),
EventType::RoomMember, user_id.clone(),
json!({"membership": "join", "displayname": displayname}), EventType::RoomMember,
None, json!({"membership": "join", "displayname": displayname}),
Some(user_id.to_string()), None,
&db.globals Some(user_id.to_string()),
).unwrap(); &db.globals,
)
.unwrap();
} }
// TODO: send a new m.presence event
// Presence update
db.global_edus
.update_globallatest(
&user_id,
EduEvent::Presence(ruma_events::presence::PresenceEvent {
content: ruma_events::presence::PresenceEventContent {
avatar_url: db.users.avatar_url(&user_id).unwrap(),
currently_active: None,
displayname: db.users.displayname(&user_id).unwrap(),
last_active_ago: Some(utils::millis_since_unix_epoch().try_into().unwrap()),
presence: ruma_events::presence::PresenceState::Online,
status_msg: None,
},
sender: user_id.clone(),
}),
&db.globals,
)
.unwrap();
} else { } else {
// Send error on None // Send error on None
// Synapse returns a parsing error but the spec doesn't require this // Synapse returns a parsing error but the spec doesn't require this
@ -542,8 +556,7 @@ pub fn set_avatar_url_route(
if body.avatar_url == "" { if body.avatar_url == "" {
db.users.set_avatar_url(&user_id, None).unwrap(); db.users.set_avatar_url(&user_id, None).unwrap();
} else { } else {
db db.users
.users
.set_avatar_url(&user_id, Some(body.avatar_url.clone())) .set_avatar_url(&user_id, Some(body.avatar_url.clone()))
.unwrap(); .unwrap();
// TODO send a new m.room.member join event with the updated avatar_url // TODO send a new m.room.member join event with the updated avatar_url
@ -605,11 +618,32 @@ pub fn get_profile_route(
})) }))
} }
#[put("/_matrix/client/r0/presence/<_user_id>/status")] #[put("/_matrix/client/r0/presence/<_user_id>/status", data = "<body>")]
pub fn set_presence_route( pub fn set_presence_route(
db: State<'_, Database>,
body: Ruma<set_presence::Request>,
_user_id: String, _user_id: String,
) -> MatrixResult<set_presence::Response> { ) -> MatrixResult<set_presence::Response> {
// TODO let user_id = body.user_id.clone().expect("user is authenticated");
db.global_edus
.update_globallatest(
&user_id,
EduEvent::Presence(ruma_events::presence::PresenceEvent {
content: ruma_events::presence::PresenceEventContent {
avatar_url: db.users.avatar_url(&user_id).unwrap(),
currently_active: None,
displayname: db.users.displayname(&user_id).unwrap(),
last_active_ago: Some(utils::millis_since_unix_epoch().try_into().unwrap()),
presence: body.presence,
status_msg: body.status_msg.clone(),
},
sender: user_id.clone(),
}),
&db.globals,
)
.unwrap();
MatrixResult(Ok(set_presence::Response)) MatrixResult(Ok(set_presence::Response))
} }
@ -637,28 +671,27 @@ pub fn set_read_marker_route(
_room_id: String, _room_id: String,
) -> MatrixResult<set_read_marker::Response> { ) -> MatrixResult<set_read_marker::Response> {
let user_id = body.user_id.clone().expect("user is authenticated"); let user_id = body.user_id.clone().expect("user is authenticated");
db.account_data.update( db.account_data
Some(&body.room_id), .update(
&user_id, Some(&body.room_id),
EduEvent::FullyRead(ruma_events::fully_read::FullyReadEvent { &user_id,
content: ruma_events::fully_read::FullyReadEventContent { EduEvent::FullyRead(ruma_events::fully_read::FullyReadEvent {
event_id: body.fully_read.clone(), content: ruma_events::fully_read::FullyReadEventContent {
}, event_id: body.fully_read.clone(),
room_id: Some(body.room_id.clone()), },
}), room_id: Some(body.room_id.clone()),
&db.globals }),
) &db.globals,
.unwrap(); )
.unwrap();
if let Some(event) = &body.read_receipt { if let Some(event) = &body.read_receipt {
db db.rooms
.rooms
.edus .edus
.room_read_set( .room_read_set(
&body.room_id, &body.room_id,
&user_id, &user_id,
db db.rooms
.rooms
.get_pdu_count(event) .get_pdu_count(event)
.unwrap() .unwrap()
.expect("TODO: what if a client specifies an invalid event"), .expect("TODO: what if a client specifies an invalid event"),
@ -680,8 +713,7 @@ pub fn set_read_marker_route(
}, },
); );
db db.rooms
.rooms
.edus .edus
.roomlatest_update( .roomlatest_update(
&user_id, &user_id,
@ -716,8 +748,7 @@ pub fn create_typing_event_route(
}); });
if body.typing { if body.typing {
db db.rooms
.rooms
.edus .edus
.roomactive_add( .roomactive_add(
edu, edu,
@ -728,11 +759,7 @@ pub fn create_typing_event_route(
) )
.unwrap(); .unwrap();
} else { } else {
db db.rooms.edus.roomactive_remove(edu, &body.room_id).unwrap();
.rooms
.edus
.roomactive_remove(edu, &body.room_id)
.unwrap();
} }
MatrixResult(Ok(create_typing_event::Response)) MatrixResult(Ok(create_typing_event::Response))
@ -747,8 +774,7 @@ pub fn create_room_route(
let room_id = RoomId::try_from(db.globals.hostname()).expect("host is valid"); let room_id = RoomId::try_from(db.globals.hostname()).expect("host is valid");
let user_id = body.user_id.clone().expect("user is authenticated"); let user_id = body.user_id.clone().expect("user is authenticated");
db db.rooms
.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
user_id.clone(), user_id.clone(),
@ -760,8 +786,7 @@ pub fn create_room_route(
) )
.unwrap(); .unwrap();
db db.rooms
.rooms
.join( .join(
&room_id, &room_id,
&user_id, &user_id,
@ -770,8 +795,7 @@ pub fn create_room_route(
) )
.unwrap(); .unwrap();
db db.rooms
.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
user_id.clone(), user_id.clone(),
@ -793,8 +817,7 @@ pub fn create_room_route(
.unwrap(); .unwrap();
if let Some(name) = &body.name { if let Some(name) = &body.name {
db db.rooms
.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
user_id.clone(), user_id.clone(),
@ -808,8 +831,7 @@ pub fn create_room_route(
} }
if let Some(topic) = &body.topic { if let Some(topic) = &body.topic {
db db.rooms
.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
user_id.clone(), user_id.clone(),
@ -823,8 +845,7 @@ pub fn create_room_route(
} }
for user in &body.invite { for user in &body.invite {
db db.rooms
.rooms
.invite(&user_id, &room_id, user, &db.globals) .invite(&user_id, &room_id, user, &db.globals)
.unwrap(); .unwrap();
} }
@ -945,8 +966,7 @@ pub fn leave_room_route(
_room_id: String, _room_id: String,
) -> MatrixResult<leave_room::Response> { ) -> MatrixResult<leave_room::Response> {
let user_id = body.user_id.clone().expect("user is authenticated"); let user_id = body.user_id.clone().expect("user is authenticated");
db db.rooms
.rooms
.leave(&user_id, &body.room_id, &user_id, &db.globals) .leave(&user_id, &body.room_id, &user_id, &db.globals)
.unwrap(); .unwrap();
MatrixResult(Ok(leave_room::Response)) MatrixResult(Ok(leave_room::Response))
@ -970,8 +990,7 @@ pub fn invite_user_route(
_room_id: String, _room_id: String,
) -> MatrixResult<invite_user::Response> { ) -> MatrixResult<invite_user::Response> {
if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient { if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient {
db db.rooms
.rooms
.invite( .invite(
&body.user_id.as_ref().expect("user is authenticated"), &body.user_id.as_ref().expect("user is authenticated"),
&body.room_id, &body.room_id,
@ -1069,16 +1088,13 @@ pub fn search_users_route(
} }
#[get("/_matrix/client/r0/rooms/<_room_id>/members")] #[get("/_matrix/client/r0/rooms/<_room_id>/members")]
pub fn get_member_events_route( pub fn get_member_events_route(_room_id: String) -> MatrixResult<get_member_events::Response> {
_room_id: String,
) -> MatrixResult<get_member_events::Response> {
// TODO // TODO
MatrixResult(Ok(get_member_events::Response { chunk: Vec::new() })) MatrixResult(Ok(get_member_events::Response { chunk: Vec::new() }))
} }
#[get("/_matrix/client/r0/thirdparty/protocols")] #[get("/_matrix/client/r0/thirdparty/protocols")]
pub fn get_protocols_route( pub fn get_protocols_route() -> MatrixResult<get_protocols::Response> {
) -> MatrixResult<get_protocols::Response> {
// TODO // TODO
MatrixResult(Ok(get_protocols::Response { MatrixResult(Ok(get_protocols::Response {
protocols: BTreeMap::new(), protocols: BTreeMap::new(),
@ -1114,7 +1130,9 @@ pub fn create_message_event_route(
) )
.expect("message events are always okay"); .expect("message events are always okay");
MatrixResult(Ok(create_message_event::Response { event_id: Some(event_id) })) MatrixResult(Ok(create_message_event::Response {
event_id: Some(event_id),
}))
} }
#[put( #[put(
@ -1144,7 +1162,9 @@ pub fn create_state_event_for_key_route(
) )
.unwrap(); .unwrap();
MatrixResult(Ok(create_state_event_for_key::Response { event_id: Some(event_id) })) MatrixResult(Ok(create_state_event_for_key::Response {
event_id: Some(event_id),
}))
} }
#[put( #[put(
@ -1173,7 +1193,9 @@ pub fn create_state_event_for_empty_key_route(
) )
.unwrap(); .unwrap();
MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id: Some(event_id) })) MatrixResult(Ok(create_state_event_for_empty_key::Response {
event_id: Some(event_id),
}))
} }
#[get("/_matrix/client/r0/sync", data = "<body>")] #[get("/_matrix/client/r0/sync", data = "<body>")]
@ -1197,7 +1219,8 @@ pub fn sync_route(
let mut pdus = db let mut pdus = db
.rooms .rooms
.pdus_since(&room_id, since).unwrap() .pdus_since(&room_id, since)
.unwrap()
.map(|r| r.unwrap()) .map(|r| r.unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -1213,16 +1236,12 @@ pub fn sync_route(
} }
} }
let notification_count = if let Some(last_read) = db let notification_count =
.rooms if let Some(last_read) = db.rooms.edus.room_read_get(&room_id, &user_id).unwrap() {
.edus Some((db.rooms.pdus_since(&room_id, last_read).unwrap().count() as u32).into())
.room_read_get(&room_id, &user_id) } else {
.unwrap() None
{ };
Some((db.rooms.pdus_since(&room_id, last_read).unwrap().count() as u32).into())
} else {
None
};
// They /sync response doesn't always return all messages, so we say the output is // They /sync response doesn't always return all messages, so we say the output is
// limited unless there are enough events // limited unless there are enough events
@ -1262,10 +1281,10 @@ pub fn sync_route(
} }
edus.extend( edus.extend(
db db.rooms
.rooms
.edus .edus
.roomlatests_since(&room_id, since).unwrap() .roomlatests_since(&room_id, since)
.unwrap()
.map(|r| r.unwrap()), .map(|r| r.unwrap()),
); );
@ -1273,8 +1292,10 @@ pub fn sync_route(
room_id.clone().try_into().unwrap(), room_id.clone().try_into().unwrap(),
sync_events::JoinedRoom { sync_events::JoinedRoom {
account_data: Some(sync_events::AccountData { account_data: Some(sync_events::AccountData {
events: db.account_data events: db
.changes_since(Some(&room_id), &user_id, since).unwrap() .account_data
.changes_since(Some(&room_id), &user_id, since)
.unwrap()
.into_iter() .into_iter()
.map(|(_, v)| v) .map(|(_, v)| v)
.collect(), .collect(),
@ -1304,8 +1325,7 @@ pub fn sync_route(
// TODO: state before timeline // TODO: state before timeline
state: sync_events::State { state: sync_events::State {
events: if send_full_state { events: if send_full_state {
db db.rooms
.rooms
.room_state(&room_id) .room_state(&room_id)
.unwrap() .unwrap()
.into_iter() .into_iter()
@ -1332,17 +1352,12 @@ pub fn sync_route(
let mut edus = db let mut edus = db
.rooms .rooms
.edus .edus
.roomlatests_since(&room_id, since).unwrap() .roomlatests_since(&room_id, since)
.unwrap()
.map(|r| r.unwrap()) .map(|r| r.unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
edus.extend( edus.extend(db.rooms.edus.roomactives_all(&room_id).map(|r| r.unwrap()));
db
.rooms
.edus
.roomactives_all(&room_id)
.map(|r| r.unwrap()),
);
left_rooms.insert( left_rooms.insert(
room_id.clone().try_into().unwrap(), room_id.clone().try_into().unwrap(),
@ -1363,7 +1378,8 @@ pub fn sync_route(
let room_id = room_id.unwrap(); let room_id = room_id.unwrap();
let events = db let events = db
.rooms .rooms
.pdus_since(&room_id, since).unwrap() .pdus_since(&room_id, since)
.unwrap()
.into_iter() .into_iter()
.map(|pdu| pdu.unwrap().to_stripped_state_event()) .map(|pdu| pdu.unwrap().to_stripped_state_event())
.collect(); .collect();
@ -1383,10 +1399,23 @@ pub fn sync_route(
join: joined_rooms, join: joined_rooms,
invite: invited_rooms, invite: invited_rooms,
}, },
presence: sync_events::Presence { events: Vec::new() }, presence: sync_events::Presence {
events: db
.global_edus
.globallatests_since(since)
.unwrap()
.map(|edu| {
EventJson::<ruma_events::presence::PresenceEvent>::from(
edu.unwrap().json().to_owned(),
)
})
.collect(),
},
account_data: sync_events::AccountData { account_data: sync_events::AccountData {
events: db.account_data events: db
.changes_since(None, &user_id, since).unwrap() .account_data
.changes_since(None, &user_id, since)
.unwrap()
.into_iter() .into_iter()
.map(|(_, v)| v) .map(|(_, v)| v)
.collect(), .collect(),

View File

@ -1,4 +1,5 @@
pub(self) mod account_data; pub(self) mod account_data;
pub(self) mod global_edus;
pub(self) mod globals; pub(self) mod globals;
pub(self) mod rooms; pub(self) mod rooms;
pub(self) mod users; pub(self) mod users;
@ -11,8 +12,7 @@ pub struct Database {
pub users: users::Users, pub users: users::Users,
pub rooms: rooms::Rooms, pub rooms: rooms::Rooms,
pub account_data: account_data::AccountData, pub account_data: account_data::AccountData,
//pub globalallid_globalall: sled::Tree, // ToDevice, GlobalAllId = UserId + Count pub global_edus: global_edus::GlobalEdus,
//pub globallatestid_globallatest: sled::Tree, // Presence, GlobalLatestId = Count + Type + UserId
pub _db: sled::Db, pub _db: sled::Db,
} }
@ -66,8 +66,10 @@ impl Database {
account_data: account_data::AccountData { account_data: account_data::AccountData {
roomuserdataid_accountdata: db.open_tree("roomuserdataid_accountdata").unwrap(), roomuserdataid_accountdata: db.open_tree("roomuserdataid_accountdata").unwrap(),
}, },
//globalallid_globalall: db.open_tree("globalallid_globalall").unwrap(), global_edus: global_edus::GlobalEdus {
//globallatestid_globallatest: db.open_tree("globallatestid_globallatest").unwrap(), //globalallid_globalall: db.open_tree("globalallid_globalall").unwrap(),
globallatestid_globallatest: db.open_tree("globallatestid_globallatest").unwrap(), // Presence
},
_db: db, _db: db,
} }
} }

View File

@ -0,0 +1,68 @@
use crate::Result;
use ruma_events::{collections::only::Event as EduEvent, EventJson};
use ruma_identifiers::UserId;
pub struct GlobalEdus {
pub(super) globallatestid_globallatest: sled::Tree, // Presence, GlobalLatestId = Count + UserId
//pub globalallid_globalall: sled::Tree, // ToDevice, GlobalAllId = UserId + Count
}
impl GlobalEdus {
/// Adds a global event which will be saved until a new event replaces it (e.g. presence updates).
pub fn update_globallatest(
&self,
user_id: &UserId,
event: EduEvent,
globals: &super::globals::Globals,
) -> Result<()> {
// Remove old entry
if let Some(old) = self
.globallatestid_globallatest
.iter()
.keys()
.rev()
.filter_map(|r| r.ok())
.find(|key| {
key.rsplit(|&b| b == 0xff).next().unwrap() == user_id.to_string().as_bytes()
})
{
// This is the old global_latest
self.globallatestid_globallatest.remove(old)?;
}
let mut global_latest_id = globals.next_count()?.to_be_bytes().to_vec();
global_latest_id.push(0xff);
global_latest_id.extend_from_slice(&user_id.to_string().as_bytes());
self.globallatestid_globallatest
.insert(global_latest_id, &*serde_json::to_string(&event)?)?;
Ok(())
}
/// Returns an iterator over the most recent presence updates that happened after the event with id `since`.
pub fn globallatests_since(
&self,
since: u64,
) -> Result<impl Iterator<Item = Result<EventJson<EduEvent>>>> {
let first_possible_edu = since.to_be_bytes().to_vec();
Ok(self
.globallatestid_globallatest
.range(&*first_possible_edu..)
// Skip the first pdu if it's exactly at since, because we sent that last time
.skip(
if self
.globallatestid_globallatest
.get(first_possible_edu)?
.is_some()
{
1
} else {
0
},
)
.filter_map(|r| r.ok())
.map(|(_, v)| Ok(serde_json::from_slice(&v)?)))
}
}

View File

@ -79,14 +79,6 @@ impl RoomEdus {
.map(|(_, v)| Ok(serde_json::from_slice(&v)?))) .map(|(_, v)| Ok(serde_json::from_slice(&v)?)))
} }
/// Returns a vector of the most recent read_receipts in a room that happened after the event with id `since`.
pub fn roomlatests_all(
&self,
room_id: &RoomId,
) -> Result<impl Iterator<Item = Result<EventJson<EduEvent>>>> {
self.roomlatests_since(room_id, 0)
}
/// Adds an event that will be saved until the `timeout` timestamp (e.g. typing notifications). /// Adds an event that will be saved until the `timeout` timestamp (e.g. typing notifications).
pub fn roomactive_add( pub fn roomactive_add(
&self, &self,

View File

@ -59,7 +59,12 @@ pub async fn send_request<T: Endpoint>(
request_map.insert("destination".to_owned(), destination.into()); request_map.insert("destination".to_owned(), destination.into());
let mut request_json = request_map.into(); let mut request_json = request_map.into();
ruma_signatures::sign_json(db.globals.hostname(), db.globals.keypair(), &mut request_json).unwrap(); ruma_signatures::sign_json(
db.globals.hostname(),
db.globals.keypair(),
&mut request_json,
)
.unwrap();
let signatures = request_json["signatures"] let signatures = request_json["signatures"]
.as_object() .as_object()
@ -85,7 +90,11 @@ pub async fn send_request<T: Endpoint>(
); );
} }
let reqwest_response = db.globals.reqwest_client().execute(http_request.into()).await; let reqwest_response = db
.globals
.reqwest_client()
.execute(http_request.into())
.await;
// Because reqwest::Response -> http::Response is complicated: // Because reqwest::Response -> http::Response is complicated:
match reqwest_response { match reqwest_response {