forked from lavina/lavina
1
0
Fork 0

send subject

This commit is contained in:
Nikita Vilunov 2024-05-15 14:18:19 +02:00
parent a22017ee8f
commit 8b05c852e7
3 changed files with 49 additions and 17 deletions

View File

@ -5,7 +5,7 @@ use quick_xml::events::Event;
use lavina_core::room::RoomId; use lavina_core::room::RoomId;
use proto_xmpp::bind::{Jid, Name, Server}; use proto_xmpp::bind::{Jid, Name, Server};
use proto_xmpp::client::Presence; use proto_xmpp::client::{Message, MessageType, Presence};
use proto_xmpp::muc::XUser; use proto_xmpp::muc::XUser;
use proto_xmpp::xml::{Ignore, ToXml}; use proto_xmpp::xml::{Ignore, ToXml};
@ -23,11 +23,30 @@ impl<'a> XmppConnection<'a> {
// resources in MUCs are members' personas not implemented (yet?) // resources in MUCs are members' personas not implemented (yet?)
resource: Some(_), resource: Some(_),
}) if server.0 == self.hostname_rooms => { }) if server.0 == self.hostname_rooms => {
let response = self.muc_presence(&name).await?; let response = self.muc_presence(p.id.as_ref(), &name).await?;
let message = Message::<()> {
to: Some(Jid {
name: Some(self.user.xmpp_name.clone()),
server: Server(self.hostname.clone()),
resource: Some(self.user.xmpp_resource.clone()),
}),
from: Some(Jid {
name: Some(name.clone()),
server: Server(self.hostname_rooms.clone()),
resource: None,
}),
r#type: MessageType::Groupchat,
subject: Some("".into()),
id: None,
lang: None,
body: "".into(),
custom: vec![],
};
response.serialize(output); response.serialize(output);
message.serialize(output);
} }
_ => { _ => {
// TODO other presence cases // TODO other presence casess
let response = Presence::<()>::default(); let response = Presence::<()>::default();
response.serialize(output); response.serialize(output);
} }
@ -56,15 +75,18 @@ impl<'a> XmppConnection<'a> {
}; };
response.serialize(output); response.serialize(output);
} }
_ => todo!(), _ => {
tracing::error!("TODO");
}
} }
} }
// todo: return Presence and serialize on the outside. // todo: return Presence and serialize on the outside.
async fn muc_presence(&mut self, name: &Name) -> Result<(Presence<XUser>)> { async fn muc_presence(&mut self, id: Option<&String>, name: &Name) -> Result<(Presence<XUser>)> {
let a = self.user_handle.join_room(RoomId::from(name.0.clone())?).await?; let a = self.user_handle.join_room(RoomId::from(name.0.clone())?).await?;
// TODO handle bans // TODO handle bans
let response = Presence { let response = Presence {
id: id.map(ToOwned::to_owned),
to: Some(Jid { to: Some(Jid {
name: Some(self.user.xmpp_name.clone()), name: Some(self.user.xmpp_name.clone()),
server: Server(self.hostname.clone()), server: Server(self.hostname.clone()),

View File

@ -20,7 +20,7 @@ pub struct Message<T> {
// default is Normal // default is Normal
pub r#type: MessageType, pub r#type: MessageType,
pub lang: Option<Str>, pub lang: Option<Str>,
pub subject: Option<Str>, pub subject: Option<Str>, // TODO there are three states of <subject -- not present, empty and some string
pub body: Str, pub body: Str,
pub custom: Vec<T>, pub custom: Vec<T>,
} }
@ -50,6 +50,7 @@ enum MessageParserInner<T: FromXml> {
InBody(MessageParserState<T>), InBody(MessageParserState<T>),
InCustom(MessageParserState<T>, T::P), InCustom(MessageParserState<T>, T::P),
} }
#[derive(Default)] #[derive(Default)]
struct MessageParserState<T> { struct MessageParserState<T> {
from: Option<Jid>, from: Option<Jid>,
@ -61,6 +62,7 @@ struct MessageParserState<T> {
body: Option<Str>, body: Option<Str>,
custom: Vec<T>, custom: Vec<T>,
} }
impl<T: FromXml> Parser for MessageParser<T> { impl<T: FromXml> Parser for MessageParser<T> {
type Output = Result<Message<T>>; type Output = Result<Message<T>>;
@ -208,9 +210,18 @@ impl<T: ToXml> ToXml for Message<T> {
value: self.r#type.as_str().as_bytes().into(), value: self.r#type.as_str().as_bytes().into(),
}); });
events.push(Event::Start(bytes)); events.push(Event::Start(bytes));
if self.subject.is_none() {
// TODO make body optional
events.push(Event::Start(BytesStart::new("body"))); events.push(Event::Start(BytesStart::new("body")));
events.push(Event::Text(BytesText::new(&self.body).into_owned())); events.push(Event::Text(BytesText::new(&self.body).into_owned()));
events.push(Event::End(BytesEnd::new("body"))); events.push(Event::End(BytesEnd::new("body")));
}
if let Some(subject) = &self.subject {
// TODO make subject tri-state
events.push(Event::Start(BytesStart::new("subject")));
events.push(Event::Text(BytesText::new(&subject).into_owned()));
events.push(Event::End(BytesEnd::new("subject")));
}
events.push(Event::End(BytesEnd::new("message"))); events.push(Event::End(BytesEnd::new("message")));
} }
} }
@ -266,6 +277,7 @@ pub struct IqError {
pub enum IqErrorCondition { pub enum IqErrorCondition {
ItemNotFound, ItemNotFound,
} }
impl IqErrorCondition { impl IqErrorCondition {
pub fn as_str(&self) -> &'static str { pub fn as_str(&self) -> &'static str {
match self { match self {
@ -286,6 +298,7 @@ pub enum IqErrorType {
/// Retry after waiting (the error is temporary) /// Retry after waiting (the error is temporary)
Wait, Wait,
} }
impl IqErrorType { impl IqErrorType {
pub fn as_str(&self) -> &'static str { pub fn as_str(&self) -> &'static str {
match self { match self {
@ -345,6 +358,7 @@ enum IqParserInner<T: FromXml> {
ParsingBody(IqParserState<T>, T::P), ParsingBody(IqParserState<T>, T::P),
Final(IqParserState<T>), Final(IqParserState<T>),
} }
struct IqParserState<T> { struct IqParserState<T> {
pub from: Option<Jid>, pub from: Option<Jid>,
pub id: Option<String>, pub id: Option<String>,
@ -706,7 +720,7 @@ mod tests {
to: Some(Jid { to: Some(Jid {
name: Some(Name("chelik".into())), name: Some(Name("chelik".into())),
server: Server("xmpp.ru".into()), server: Server("xmpp.ru".into()),
resource: None resource: None,
}), }),
r#type: MessageType::Chat, r#type: MessageType::Chat,
lang: None, lang: None,
@ -729,7 +743,7 @@ mod tests {
to: Some(Jid { to: Some(Jid {
name: Some(Name("chelik".into())), name: Some(Name("chelik".into())),
server: Server("xmpp.ru".into()), server: Server("xmpp.ru".into()),
resource: None resource: None,
}), }),
r#type: MessageType::Chat, r#type: MessageType::Chat,
lang: None, lang: None,
@ -751,7 +765,7 @@ mod tests {
id: "bind_1".to_string(), id: "bind_1".to_string(),
to: None, to: None,
r#type: IqType::Set, r#type: IqType::Set,
body: BindRequest(Resource("mobile".into())) body: BindRequest(Resource("mobile".into())),
} }
) )
} }

View File

@ -155,13 +155,9 @@ impl ToXml for XUser {
let mut meg = BytesStart::new("item"); let mut meg = BytesStart::new("item");
meg.push_attribute(("affiliation", "owner")); meg.push_attribute(("affiliation", "owner"));
meg.push_attribute(("role", "moderator")); meg.push_attribute(("role", "moderator"));
meg.push_attribute(("jid", "sauer@localhost")); meg.push_attribute(("jid", "user@localhost/user"));
output.push(Event::Empty(meg)); output.push(Event::Empty(meg));
let mut veg = BytesStart::new("status");
veg.push_attribute(("code", "100"));
output.push(Event::Empty(veg));
let mut veg = BytesStart::new("status"); let mut veg = BytesStart::new("status");
veg.push_attribute(("code", "110")); veg.push_attribute(("code", "110"));
output.push(Event::Empty(veg)); output.push(Event::Empty(veg));