Implement reactions

This commit is contained in:
link2xt
2022-10-04 13:19:04 +00:00
parent 895c723d4e
commit d34f9e23fe
23 changed files with 804 additions and 22 deletions

View File

@@ -465,7 +465,10 @@ impl MimeMessage {
| Viewtype::Video
| Viewtype::File
| Viewtype::Webxdc => true,
Viewtype::Unknown | Viewtype::Text | Viewtype::VideochatInvitation => false,
Viewtype::Unknown
| Viewtype::Text
| Viewtype::Reaction
| Viewtype::VideochatInvitation => false,
};
if need_drop {
@@ -551,7 +554,10 @@ impl MimeMessage {
}
if prepend_subject && !subject.is_empty() {
let part_with_text = self.parts.iter_mut().find(|part| !part.msg.is_empty());
let part_with_text = self
.parts
.iter_mut()
.find(|part| !part.msg.is_empty() && part.typ != Viewtype::Reaction);
if let Some(mut part) = part_with_text {
part.msg = format!("{} {}", subject, part.msg);
}
@@ -913,6 +919,7 @@ impl MimeMessage {
Ok(any_part_added)
}
/// Returns true if any part was added, false otherwise.
async fn add_single_part_if_known(
&mut self,
context: &Context,
@@ -946,6 +953,26 @@ impl MimeMessage {
warn!(context, "Missing attachment");
return Ok(false);
}
mime::TEXT if msg_type == Viewtype::Reaction => {
// Reaction.
let decoded_data = match mail.get_body() {
Ok(decoded_data) => decoded_data,
Err(err) => {
warn!(context, "Invalid body parsed {:?}", err);
// Note that it's not always an error - might be no data
return Ok(false);
}
};
let part = Part {
typ: Viewtype::Reaction,
mimetype: Some(mime_type),
msg: decoded_data,
..Default::default()
};
self.do_add_single_part(part);
return Ok(true);
}
mime::TEXT | mime::HTML => {
let decoded_data = match mail.get_body() {
Ok(decoded_data) => decoded_data,
@@ -1652,7 +1679,11 @@ fn get_mime_type(mail: &mailparse::ParsedMail<'_>) -> Result<(Mime, Viewtype)> {
let viewtype = match mimetype.type_() {
mime::TEXT => {
if !is_attachment_disposition(mail) {
if mail.get_content_disposition().disposition
== DispositionType::Extension("reaction".to_string())
{
Viewtype::Reaction
} else if !is_attachment_disposition(mail) {
match mimetype.subtype() {
mime::PLAIN | mime::HTML => Viewtype::Text,
_ => Viewtype::File,
@@ -3329,4 +3360,39 @@ Message.
Ok(())
}
/// Tests parsing of MIME message containing RFC 9078 reaction.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_parse_reaction() -> Result<()> {
let alice = TestContext::new_alice().await;
let mime_message = MimeMessage::from_bytes(
&alice,
"To: alice@example.org\n\
From: bob@example.net\n\
Date: Today, 29 February 2021 00:00:10 -800\n\
Message-ID: 56789@example.net\n\
In-Reply-To: 12345@example.org\n\
Subject: Meeting\n\
Mime-Version: 1.0 (1.0)\n\
Content-Type: text/plain; charset=utf-8\n\
Content-Disposition: reaction\n\
\n\
\u{1F44D}"
.as_bytes(),
)
.await?;
assert_eq!(mime_message.parts.len(), 1);
assert_eq!(mime_message.parts[0].typ, Viewtype::Reaction);
assert_eq!(
mime_message
.get_header(HeaderDef::InReplyTo)
.and_then(|msgid| parse_message_id(msgid).ok())
.unwrap(),
"12345@example.org"
);
Ok(())
}
}