mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
add dc_msg_set_html() api (#2153)
* draft dc_msg_set_html() api * implement setting 'html to be send' * test sending html-parts * more flexible html-partbuilder * write html-parts to database and also send them * add 'sendhtml' command to repl tool
This commit is contained in:
81
src/html.rs
81
src/html.rs
@@ -17,6 +17,7 @@ use crate::context::Context;
|
||||
use crate::headerdef::{HeaderDef, HeaderDefMap};
|
||||
use crate::message::{Message, MsgId};
|
||||
use crate::mimeparser::parse_message_id;
|
||||
use crate::param::Param::SendHtml;
|
||||
use crate::plaintext::PlainText;
|
||||
use lettre_email::PartBuilder;
|
||||
use mailparse::ParsedContentType;
|
||||
@@ -31,6 +32,24 @@ impl Message {
|
||||
pub fn has_html(&self) -> bool {
|
||||
self.mime_modified
|
||||
}
|
||||
|
||||
/// Set HTML-part part of a message that is about to be sent.
|
||||
/// The HTML-part is written to the database before sending and
|
||||
/// used as the `text/html` part in the MIME-structure.
|
||||
///
|
||||
/// Received HTML parts are handled differently,
|
||||
/// they are saved together with the whole MIME-structure
|
||||
/// in `mime_headers` and the HTML-part is extracted using `MsgId::get_html()`.
|
||||
/// (To underline this asynchronicity, we are using the wording "SendHtml")
|
||||
pub fn set_html(&mut self, html: Option<String>) {
|
||||
if let Some(html) = html {
|
||||
self.param.set(SendHtml, html);
|
||||
self.mime_modified = true;
|
||||
} else {
|
||||
self.param.remove(SendHtml);
|
||||
self.mime_modified = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Type defining a rough mime-type.
|
||||
@@ -250,33 +269,25 @@ impl MsgId {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps HTML generated by [`MsgId::get_html`] into a text/html mimepart structure.
|
||||
///
|
||||
/// Used on forwarding messages to avoid leaking the original mime structure
|
||||
/// and also to avoid sending too much, maybe large data.
|
||||
pub async fn get_html_as_mimepart(self, context: &Context) -> Option<PartBuilder> {
|
||||
self.get_html(context).await.map(|s| {
|
||||
PartBuilder::new()
|
||||
.content_type(&"text/html; charset=utf-8".parse::<mime::Mime>().unwrap())
|
||||
.body(s)
|
||||
})
|
||||
}
|
||||
|
||||
// As [`MsgId::get_html_as_mimepart`] but wraps [`MsgId::get_html`] into text/html mime raw string.
|
||||
pub async fn get_html_as_rawmime(self, context: &Context) -> Option<String> {
|
||||
self.get_html_as_mimepart(context)
|
||||
.await
|
||||
.map(|p| p.build().as_string())
|
||||
}
|
||||
/// Wraps HTML text into a new text/html mimepart structure.
|
||||
///
|
||||
/// Used on forwarding messages to avoid leaking the original mime structure
|
||||
/// and also to avoid sending too much, maybe large data.
|
||||
pub async fn new_html_mimepart(html: String) -> PartBuilder {
|
||||
PartBuilder::new()
|
||||
.content_type(&"text/html; charset=utf-8".parse::<mime::Mime>().unwrap())
|
||||
.body(html)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::chat;
|
||||
use crate::chat::forward_msgs;
|
||||
use crate::config::Config;
|
||||
use crate::constants::DC_CONTACT_ID_SELF;
|
||||
use crate::constants::{Viewtype, DC_CONTACT_ID_SELF};
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::message::MessengerMessage;
|
||||
use crate::test_utils::TestContext;
|
||||
@@ -519,4 +530,36 @@ test some special html-characters as < > and & but also " and &#x
|
||||
let html = msg.get_id().get_html(&alice).await.unwrap();
|
||||
assert!(html.find("this is <b>html</b>").is_some());
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_set_html() {
|
||||
let alice = TestContext::new_alice().await;
|
||||
let bob = TestContext::new_bob().await;
|
||||
|
||||
// alice sends a message with html-part to bob
|
||||
let chat_id = alice.create_chat(&bob).await.id;
|
||||
let mut msg = Message::new(Viewtype::Text);
|
||||
msg.set_text(Some("plain text".to_string()));
|
||||
msg.set_html(Some("<b>html</b> text".to_string()));
|
||||
assert!(msg.mime_modified);
|
||||
chat::send_msg(&alice, chat_id, &mut msg).await.unwrap();
|
||||
|
||||
// check the message is written correctly to alice's db
|
||||
let msg = alice.get_last_msg_in(chat_id).await;
|
||||
assert_eq!(msg.get_text(), Some("plain text".to_string()));
|
||||
assert!(!msg.is_forwarded());
|
||||
assert!(msg.mime_modified);
|
||||
let html = msg.get_id().get_html(&alice).await.unwrap();
|
||||
assert!(html.find("<b>html</b> text").is_some());
|
||||
|
||||
// let bob receive the message
|
||||
let chat_id = bob.create_chat(&alice).await.id;
|
||||
bob.recv_msg(&alice.pop_sent_msg().await).await;
|
||||
let msg = bob.get_last_msg_in(chat_id).await;
|
||||
assert_eq!(msg.get_text(), Some("plain text".to_string()));
|
||||
assert!(!msg.is_forwarded());
|
||||
assert!(msg.mime_modified);
|
||||
let html = msg.get_id().get_html(&bob).await.unwrap();
|
||||
assert!(html.find("<b>html</b> text").is_some());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user