Skip to content

Commit 567861b

Browse files
committed
feat: truncate long messages when loading instead of saving
1 parent 99aa99e commit 567861b

File tree

6 files changed

+44
-53
lines changed

6 files changed

+44
-53
lines changed

src/chat.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use crate::sync::{self, Sync::*, SyncData};
4949
use crate::tools::{
5050
IsNoneOrEmpty, SystemTime, buf_compress, create_broadcast_secret, create_id,
5151
create_outgoing_rfc724_mid, create_smeared_timestamp, create_smeared_timestamps, get_abs_path,
52-
gm2local_offset, normalize_text, smeared_time, time, truncate_msg_text,
52+
gm2local_offset, normalize_text, smeared_time, time,
5353
};
5454
use crate::webxdc::StatusUpdateSerial;
5555

@@ -1884,7 +1884,8 @@ impl Chat {
18841884
EphemeralTimer::Enabled { duration } => time().saturating_add(duration.into()),
18851885
};
18861886

1887-
let (msg_text, was_truncated) = truncate_msg_text(context, msg.text.clone()).await?;
1887+
let msg_text = msg.text.clone();
1888+
18881889
let new_mime_headers = if msg.has_html() {
18891890
if msg.param.exists(Param::Forwarded) {
18901891
msg.get_id().get_html(context).await?
@@ -1901,13 +1902,6 @@ impl Chat {
19011902
html_part.write_part(cursor).ok();
19021903
String::from_utf8_lossy(&buffer).to_string()
19031904
});
1904-
let new_mime_headers = new_mime_headers.or_else(|| match was_truncated {
1905-
// We need to add some headers so that they are stripped before formatting HTML by
1906-
// `MsgId::get_html()`, not a part of the actual text. Let's add "Content-Type", it's
1907-
// anyway a useful metadata about the stored text.
1908-
true => Some("Content-Type: text/plain; charset=utf-8\r\n\r\n".to_string() + &msg.text),
1909-
false => None,
1910-
});
19111905
let new_mime_headers = match new_mime_headers {
19121906
Some(h) => Some(tokio::task::block_in_place(move || {
19131907
buf_compress(h.as_bytes())

src/html.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl Message {
3030
/// The corresponding ffi-function is `dc_msg_has_html()`.
3131
/// To get the HTML-code of the message, use `MsgId.get_html()`.
3232
pub fn has_html(&self) -> bool {
33-
self.mime_modified
33+
self.mime_modified || self.full_text.is_some()
3434
}
3535

3636
/// Set HTML-part part of a message that is about to be sent.
@@ -270,8 +270,18 @@ impl MsgId {
270270
Ok((parser, _)) => Ok(Some(parser.html)),
271271
}
272272
} else {
273-
warn!(context, "get_html: no mime for {}", self);
274-
Ok(None)
273+
let msg = Message::load_from_db(context, self).await?;
274+
if let Some(full_text) = &msg.full_text {
275+
let html = PlainText {
276+
text: full_text.clone(),
277+
flowed: false,
278+
delsp: false
279+
}.to_html();
280+
Ok(Some(html))
281+
} else {
282+
warn!(context, "get_html: no mime for {}", self);
283+
Ok(None)
284+
}
275285
}
276286
}
277287
}

src/message.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ use crate::reaction::get_msg_reactions;
3535
use crate::sql;
3636
use crate::summary::Summary;
3737
use crate::sync::SyncData;
38-
use crate::tools::create_outgoing_rfc724_mid;
3938
use crate::tools::{
4039
buf_compress, buf_decompress, get_filebytes, get_filemeta, gm2local_offset, read_file,
41-
sanitize_filename, time, timestamp_to_str,
40+
sanitize_filename, time, timestamp_to_str, truncate_msg_text,
41+
create_outgoing_rfc724_mid
4242
};
4343

4444
/// Message ID, including reserved IDs.
@@ -431,7 +431,13 @@ pub struct Message {
431431
pub(crate) timestamp_rcvd: i64,
432432
pub(crate) ephemeral_timer: EphemeralTimer,
433433
pub(crate) ephemeral_timestamp: i64,
434+
435+
/// Message text, possibly truncated if the message is large.
434436
pub(crate) text: String,
437+
438+
/// Full text if the message text is truncated.
439+
pub(crate) full_text: Option<String>,
440+
435441
/// Text that is added to the end of Message.text
436442
///
437443
/// Currently used for adding the download information on pre-messages
@@ -556,6 +562,7 @@ impl Message {
556562
}
557563
_ => String::new(),
558564
};
565+
559566
let msg = Message {
560567
id: row.get("id")?,
561568
rfc724_mid: row.get::<_, String>("rfc724mid")?,
@@ -580,6 +587,7 @@ impl Message {
580587
original_msg_id: row.get("original_msg_id")?,
581588
mime_modified: row.get("mime_modified")?,
582589
text,
590+
full_text: None,
583591
additional_text: String::new(),
584592
subject: row.get("subject")?,
585593
param: row.get::<_, String>("param")?.parse().unwrap_or_default(),
@@ -597,6 +605,15 @@ impl Message {
597605
.with_context(|| format!("failed to load message {id} from the database"))?;
598606

599607
if let Some(msg) = &mut msg {
608+
if !msg.mime_modified {
609+
let (truncated_text, was_truncated) =
610+
truncate_msg_text(context, msg.text.clone()).await?;
611+
if was_truncated {
612+
msg.full_text = Some(msg.text.clone());
613+
msg.text = truncated_text;
614+
}
615+
}
616+
600617
msg.additional_text =
601618
Self::get_additional_text(context, msg.download_state, &msg.param).await?;
602619
}

src/mimeparser.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ use crate::message::{self, Message, MsgId, Viewtype, get_vcard_summary, set_msg_
3232
use crate::param::{Param, Params};
3333
use crate::simplify::{SimplifiedText, simplify};
3434
use crate::sync::SyncItems;
35-
use crate::tools::{
36-
get_filemeta, parse_receive_headers, smeared_time, time, truncate_msg_text, validate_id,
37-
};
35+
use crate::tools::{get_filemeta, parse_receive_headers, smeared_time, time, validate_id};
3836
use crate::{chatlist_events, location, tools};
3937

4038
/// Public key extracted from `Autocrypt-Gossip`
@@ -1445,12 +1443,6 @@ impl MimeMessage {
14451443
(simplified_txt, top_quote)
14461444
};
14471445

1448-
let (simplified_txt, was_truncated) =
1449-
truncate_msg_text(context, simplified_txt).await?;
1450-
if was_truncated {
1451-
self.is_mime_modified = was_truncated;
1452-
}
1453-
14541446
if !simplified_txt.is_empty() || simplified_quote.is_some() {
14551447
let mut part = Part {
14561448
dehtml_failed,

src/mimeparser/mimeparser_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,12 +1283,12 @@ async fn test_mime_modified_large_plain() -> Result<()> {
12831283

12841284
{
12851285
let mimemsg = MimeMessage::from_bytes(&t, long_txt.as_ref()).await?;
1286-
assert!(mimemsg.is_mime_modified);
1286+
assert!(!mimemsg.is_mime_modified);
12871287
assert!(
12881288
mimemsg.parts[0].msg.matches("just repeated").count()
1289-
<= DC_DESIRED_TEXT_LEN / REPEAT_TXT.len()
1289+
== REPEAT_CNT
12901290
);
1291-
assert!(mimemsg.parts[0].msg.len() <= DC_DESIRED_TEXT_LEN + DC_ELLIPSIS.len());
1291+
assert_eq!(mimemsg.parts[0].msg.len() + 1, REPEAT_TXT.len() * REPEAT_CNT);
12921292
}
12931293

12941294
for draft in [false, true] {

src/receive_imf/receive_imf_tests.rs

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3583,39 +3583,17 @@ async fn test_big_forwarded_with_big_attachment() -> Result<()> {
35833583
.starts_with("this text with 42 chars is just repeated.")
35843584
);
35853585
assert!(msg.get_text().ends_with("[...]"));
3586-
assert!(!msg.has_html());
3587-
3588-
let msg = Message::load_from_db(t, rcvd.msg_ids[2]).await?;
3589-
assert_eq!(msg.get_viewtype(), Viewtype::File);
35903586
assert!(msg.has_html());
35913587
let html = msg.id.get_html(t).await?.unwrap();
3592-
let tail = html
3593-
.split_once("Hello!")
3594-
.unwrap()
3595-
.1
3596-
.split_once("From: AAA")
3597-
.unwrap()
3598-
.1
3599-
.split_once("aaa@example.org")
3600-
.unwrap()
3601-
.1
3602-
.split_once("To: Alice")
3603-
.unwrap()
3604-
.1
3605-
.split_once("alice@example.org")
3606-
.unwrap()
3607-
.1
3608-
.split_once("Subject: Some subject")
3609-
.unwrap()
3610-
.1
3611-
.split_once("Date: Fri, 2 Jun 2023 12:29:17 +0000")
3612-
.unwrap()
3613-
.1;
36143588
assert_eq!(
3615-
tail.matches("this text with 42 chars is just repeated.")
3589+
html.matches("this text with 42 chars is just repeated.")
36163590
.count(),
36173591
128
36183592
);
3593+
3594+
let msg = Message::load_from_db(t, rcvd.msg_ids[2]).await?;
3595+
assert_eq!(msg.get_viewtype(), Viewtype::File);
3596+
assert!(!msg.has_html());
36193597
Ok(())
36203598
}
36213599

0 commit comments

Comments
 (0)