|
1 | 1 | //! # MIME message parsing module.
|
2 | 2 |
|
| 3 | +use std::cmp::min; |
3 | 4 | use std::collections::{HashMap, HashSet};
|
4 | 5 | use std::future::Future;
|
5 | 6 | use std::path::Path;
|
@@ -37,8 +38,8 @@ use crate::simplify::{simplify, SimplifiedText};
|
37 | 38 | use crate::stock_str;
|
38 | 39 | use crate::sync::SyncItems;
|
39 | 40 | use crate::tools::{
|
40 |
| - create_smeared_timestamp, get_filemeta, parse_receive_headers, strip_rtlo_characters, |
41 |
| - truncate_by_lines, |
| 41 | + create_smeared_timestamp, get_filemeta, parse_receive_headers, smeared_time, |
| 42 | + strip_rtlo_characters, truncate_by_lines, |
42 | 43 | };
|
43 | 44 | use crate::{location, tools};
|
44 | 45 |
|
@@ -118,6 +119,12 @@ pub(crate) struct MimeMessage {
|
118 | 119 |
|
119 | 120 | /// Whether the contact sending this should be marked as bot.
|
120 | 121 | pub(crate) is_bot: bool,
|
| 122 | + |
| 123 | + /// When the message was received, in secs since epoch. |
| 124 | + pub(crate) timestamp_rcvd: i64, |
| 125 | + /// Sender timestamp in secs since epoch. Allowed to be in the future due to unsynchronized |
| 126 | + /// clocks, but not too much. |
| 127 | + pub(crate) timestamp_sent: i64, |
121 | 128 | }
|
122 | 129 |
|
123 | 130 | #[derive(Debug, PartialEq)]
|
@@ -386,6 +393,12 @@ impl MimeMessage {
|
386 | 393 | // Auto-submitted is also set by holiday-notices so we also check `chat-version`
|
387 | 394 | let is_bot = headers.contains_key("auto-submitted") && headers.contains_key("chat-version");
|
388 | 395 |
|
| 396 | + let timestamp_rcvd = smeared_time(context); |
| 397 | + let timestamp_sent = headers |
| 398 | + .get(HeaderDef::Date.get_headername()) |
| 399 | + .and_then(|value| mailparse::dateparse(value).ok()) |
| 400 | + .map_or(timestamp_rcvd, |value| min(value, timestamp_rcvd + 60)); |
| 401 | + |
389 | 402 | let mut parser = MimeMessage {
|
390 | 403 | parts: Vec::new(),
|
391 | 404 | headers,
|
@@ -415,6 +428,8 @@ impl MimeMessage {
|
415 | 428 | decoded_data: Vec::new(),
|
416 | 429 | hop_info,
|
417 | 430 | is_bot,
|
| 431 | + timestamp_rcvd, |
| 432 | + timestamp_sent, |
418 | 433 | };
|
419 | 434 |
|
420 | 435 | match partial {
|
@@ -1630,21 +1645,15 @@ impl MimeMessage {
|
1630 | 1645 | /// Handle reports
|
1631 | 1646 | /// (MDNs = Message Disposition Notification, the message was read
|
1632 | 1647 | /// and NDNs = Non delivery notification, the message could not be delivered)
|
1633 |
| - pub async fn handle_reports( |
1634 |
| - &self, |
1635 |
| - context: &Context, |
1636 |
| - from_id: ContactId, |
1637 |
| - sent_timestamp: i64, |
1638 |
| - parts: &[Part], |
1639 |
| - ) { |
| 1648 | + pub async fn handle_reports(&self, context: &Context, from_id: ContactId, parts: &[Part]) { |
1640 | 1649 | for report in &self.mdn_reports {
|
1641 | 1650 | for original_message_id in report
|
1642 | 1651 | .original_message_id
|
1643 | 1652 | .iter()
|
1644 | 1653 | .chain(&report.additional_message_ids)
|
1645 | 1654 | {
|
1646 | 1655 | if let Err(err) =
|
1647 |
| - handle_mdn(context, from_id, original_message_id, sent_timestamp).await |
| 1656 | + handle_mdn(context, from_id, original_message_id, self.timestamp_sent).await |
1648 | 1657 | {
|
1649 | 1658 | warn!(context, "Could not handle MDN: {err:#}.");
|
1650 | 1659 | }
|
|
0 commit comments