This commit is contained in:
Nikita Vilunov 2024-05-25 23:16:45 +02:00
parent ca908dea12
commit 8a8cb0da5c
6 changed files with 27 additions and 54 deletions

View File

@ -112,7 +112,7 @@ impl PlayerConnection {
} }
#[tracing::instrument(skip(self), name = "PlayerConnection::get_room_message_history")] #[tracing::instrument(skip(self), name = "PlayerConnection::get_room_message_history")]
pub async fn get_room_message_history(&self, room_id: RoomId) -> Result<(Vec<StoredMessage>)> { pub async fn get_room_message_history(&self, room_id: RoomId) -> Result<Vec<StoredMessage>> {
let (promise, deferred) = oneshot(); let (promise, deferred) = oneshot();
let cmd = ClientCommand::GetRoomHistory { room_id, promise }; let cmd = ClientCommand::GetRoomHistory { room_id, promise };
self.player_handle.send(ActorCommand::ClientCommand(cmd, self.connection_id.clone())).await; self.player_handle.send(ActorCommand::ClientCommand(cmd, self.connection_id.clone())).await;
@ -525,7 +525,6 @@ impl Player {
let result = self.get_room_history(room_id).await; let result = self.get_room_history(room_id).await;
let _ = promise.send(result); let _ = promise.send(result);
} }
_ => {}
} }
} }

View File

@ -3,7 +3,7 @@ use chrono::{DateTime, Utc};
use sqlx::FromRow; use sqlx::FromRow;
use crate::repo::Storage; use crate::repo::Storage;
use crate::room::{RoomId, StoredMessage, StoredUser}; use crate::room::{RoomId, StoredMessage};
#[derive(FromRow)] #[derive(FromRow)]
pub struct StoredRoom { pub struct StoredRoom {
@ -38,7 +38,6 @@ impl Storage {
messages.id as id, messages.id as id,
content, content,
created_at, created_at,
users.id as author_id,
users.name as author_name users.name as author_name
from from
messages messages

View File

@ -286,30 +286,10 @@ pub struct RoomInfo {
pub topic: Str, pub topic: Str,
} }
#[derive(Debug)] #[derive(Debug, FromRow)]
pub struct StoredUser {
pub id: u32,
pub name: String,
}
#[derive(Debug)]
pub struct StoredMessage { pub struct StoredMessage {
pub id: u32, pub id: u32,
pub author: StoredUser, pub author_name: String,
pub content: String, pub content: String,
pub created_at: DateTime<Utc>, pub created_at: DateTime<Utc>,
} }
impl FromRow<'_, SqliteRow> for StoredMessage {
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
Ok(Self {
id: row.try_get("id")?,
author: StoredUser {
id: row.try_get("author_id")?,
name: row.try_get("author_name")?,
},
content: row.try_get("content")?,
created_at: row.try_get("created_at")?,
})
}
}

View File

@ -2,7 +2,6 @@
use anyhow::Result; use anyhow::Result;
use quick_xml::events::Event; use quick_xml::events::Event;
use serde::Serialize;
use lavina_core::room::RoomId; use lavina_core::room::RoomId;
use proto_xmpp::bind::{Jid, Name, Resource, Server}; use proto_xmpp::bind::{Jid, Name, Resource, Server};
@ -45,12 +44,13 @@ impl<'a> XmppConnection<'a> {
custom: vec![], custom: vec![],
}; };
muc_presence.serialize(output); muc_presence.serialize(output);
subject.serialize(output);
let messages = self.retrieve_message_history(&name).await?; let messages = self.retrieve_message_history(&name).await?;
for message in messages { for message in messages {
message.serialize(output) message.serialize(output)
} }
// The subject is the last stanza sent during a MUC join process.
subject.serialize(output);
} }
_ => { _ => {
// TODO other presence cases // TODO other presence cases
@ -88,7 +88,7 @@ impl<'a> XmppConnection<'a> {
} }
} }
async fn retrieve_muc_presence(&mut self, name: &Name) -> Result<(Presence<XUser>)> { async fn retrieve_muc_presence(&mut self, name: &Name) -> Result<Presence<XUser>> {
let a = self.user_handle.join_room(RoomId::try_from(name.0.clone())?).await?; let a = self.user_handle.join_room(RoomId::try_from(name.0.clone())?).await?;
// TODO handle bans // TODO handle bans
let response = Presence { let response = Presence {
@ -120,18 +120,11 @@ impl<'a> XmppConnection<'a> {
Ok(response) Ok(response)
} }
/* /// Retrieve a room's message history. The output can be serialized into a stream of XML stanzas.
Retrieve a room's message history. The output can be serialized into a stream of XML stanzas. ///
/// Example in [XmppHistoryMessage]'s docs.
Example of such a stanza:
<message from="duqedadi@conference.oflor.me/misha" xml:lang="en" to="misha@oflor.me/tux" type="groupchat" id="7ca7cb14-b2af-49c9-bd90-05dabb1113a5">
<delay xmlns="urn:xmpp:delay" stamp="2024-05-17T16:05:28.440337Z" from="duqedadi@conference.oflor.me"/>
<body></body>
</message>
*/
#[tracing::instrument(skip(self), name = "XmppConnection::retrieve_message_history")] #[tracing::instrument(skip(self), name = "XmppConnection::retrieve_message_history")]
async fn retrieve_message_history(&self, room_name: &Name) -> Result<(Vec<XmppHistoryMessage>)> { async fn retrieve_message_history(&self, room_name: &Name) -> Result<Vec<XmppHistoryMessage>> {
let room_id = RoomId::try_from(room_name.0.clone())?; let room_id = RoomId::try_from(room_name.0.clone())?;
let history_messages = self.user_handle.get_room_message_history(room_id).await?; let history_messages = self.user_handle.get_room_message_history(room_id).await?;
let mut response = vec![]; let mut response = vec![];
@ -147,11 +140,11 @@ impl<'a> XmppConnection<'a> {
from: Jid { from: Jid {
name: Option::from(room_name.clone()), name: Option::from(room_name.clone()),
server: Server(self.hostname_rooms.clone()), server: Server(self.hostname_rooms.clone()),
resource: Option::from(Resource(history_message.author.name.clone().into())), resource: Option::from(Resource(history_message.author_name.clone().into())),
}, },
delay: Delay { delay: Delay {
from: Jid { from: Jid {
name: Option::from(Name(history_message.author.name.clone().into())), name: Option::from(Name(history_message.author_name.clone().into())),
server: Server(self.hostname_rooms.clone()), server: Server(self.hostname_rooms.clone()),
resource: None, resource: None,
}, },
@ -161,7 +154,7 @@ impl<'a> XmppConnection<'a> {
}); });
tracing::info!( tracing::info!(
"Retrieved message: {:?} {:?}", "Retrieved message: {:?} {:?}",
history_message.author, history_message.author_name,
history_message.content.clone() history_message.content.clone()
); );
} }

View File

@ -15,7 +15,8 @@ pub mod streamerror;
pub mod tls; pub mod tls;
pub mod xml; pub mod xml;
pub mod testkit; #[cfg(test)]
mod testkit;
// Implemented as a macro instead of a fn due to borrowck limitations // Implemented as a macro instead of a fn due to borrowck limitations
macro_rules! skip_text { macro_rules! skip_text {

View File

@ -280,14 +280,15 @@ impl ToXml for Delay {
} }
} }
/* /// Message-stanza of a historic message.
Example of an XMPP message with a history stanza: ///
/// Example:
<message from="duqedadi@conference.oflor.me/misha" xml:lang="en" to="misha@oflor.me/tux" type="groupchat" id="7ca7cb14-b2af-49c9-bd90-05dabb1113a5"> /// ```xml
<delay xmlns="urn:xmpp:delay" stamp="2024-05-17T16:05:28.440337Z" from="duqedadi@conference.oflor.me"/> /// <message from="duqedadi@conference.example.com/misha" xml:lang="en" to="misha@example.com/tux" type="groupchat" id="7ca7cb14-b2af-49c9-bd90-05dabb1113a5">
<body></body> /// <delay xmlns="urn:xmpp:delay" stamp="2024-05-17T16:05:28.440337Z" from="duqedadi@conference.example.com"/>
</message> /// <body></body>
*/ /// </message>
/// ```
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct XmppHistoryMessage { pub struct XmppHistoryMessage {
pub id: String, pub id: String,
@ -420,7 +421,7 @@ mod test {
let history_message = XmppHistoryMessage { let history_message = XmppHistoryMessage {
id: "id".to_string(), id: "id".to_string(),
to: Jid { to: Jid {
name: Some(Name("sauer@oflor.me".into())), name: Some(Name("sauer@example.com".into())),
server: Server("localhost".into()), server: Server("localhost".into()),
resource: Some(Resource("tester".into())), resource: Some(Resource("tester".into())),
}, },
@ -440,7 +441,7 @@ mod test {
body: "Hello World.".to_string(), body: "Hello World.".to_string(),
}; };
let mut events = vec![]; let mut events = vec![];
let expected = r#"<message id="id" to="sauer@oflor.me@localhost/tester" from="pepe@rooms.localhost/sauer" type="groupchat"><delay xmlns="urn:xmpp:delay" from="pepe@rooms.localhost/tester" stamp="2021-10-10T10:10:10Z"/><body>Hello World.</body></message>"#; let expected = r#"<message id="id" to="sauer@example.com@localhost/tester" from="pepe@rooms.localhost/sauer" type="groupchat"><delay xmlns="urn:xmpp:delay" from="pepe@rooms.localhost/tester" stamp="2021-10-10T10:10:10Z"/><body>Hello World.</body></message>"#;
// Act // Act
history_message.serialize(&mut events); history_message.serialize(&mut events);