message: add utc-offset field

Add a new db field for storing UTC-offset for the Date: field.
This commit is contained in:
Dirk-Jan C. Binnema
2026-07-27 20:55:52 +03:00
committed by Seth Ladygo
parent 501d27ad89
commit 0bea84adce
5 changed files with 38 additions and 10 deletions

View File

@ -68,7 +68,7 @@ struct Field {
// XXX: re-order when we update the db-schema. // XXX: re-order when we update the db-schema.
Labels, /**< Labels */ Labels, /**< Labels */
UtcOffset, /**< Offset from UTC for the sent Date */
// //
_count_ /**< Number of Ids */ _count_ /**< Number of Ids */
}; };
@ -465,6 +465,8 @@ inline constexpr std::array<Field, Field::id_size()>
Field::Flag::NormalTerm | Field::Flag::NormalTerm |
Field::Flag::PhrasableTerm, Field::Flag::PhrasableTerm,
}, },
// at the end for now; reordering when we're bumping
// the db schema version.
{ {
Field::Id::Labels, Field::Id::Labels,
Field::Type::StringList, Field::Type::StringList,
@ -475,7 +477,16 @@ inline constexpr std::array<Field, Field::id_size()>
Field::Flag::BooleanTerm | Field::Flag::BooleanTerm |
Field::Flag::Value | Field::Flag::Value |
Field::Flag::IncludeInSexp Field::Flag::IncludeInSexp
, },
{
Field::Id::UtcOffset,
Field::Type::Integer,
"utc-offset", {},
"UTC offset for Date in seconds:",
{},
'u',
Field::Flag::Value |
Field::Flag::IncludeInSexp
}, },
}}; }};

View File

@ -741,7 +741,10 @@ fill_document(Message::Private& priv)
doc.add(field.id, priv.ctime); doc.add(field.id, priv.ctime);
break; break;
case Field::Id::Date: case Field::Id::Date:
doc.add(field.id, mime_msg.date()); if (const auto& date{mime_msg.date()}; date) {
doc.add(field.id, date->first);
doc.add(Field::Id::UtcOffset, date->second);
}
break; break;
case Field::Id::EmbeddedText: case Field::Id::EmbeddedText:
doc.add(field.id, priv.embedded); doc.add(field.id, priv.embedded);
@ -801,6 +804,8 @@ fill_document(Message::Private& priv)
case Field::Id::To: case Field::Id::To:
doc.add(field.id, mime_msg.contacts(Contact::Type::To)); doc.add(field.id, mime_msg.contacts(Contact::Type::To));
break; break;
case Field::Id::UtcOffset:
break; // handle already as part of Date:
/* LCOV_EXCL_START */ /* LCOV_EXCL_START */
case Field::Id::_count_: case Field::Id::_count_:
default: default:

View File

@ -334,13 +334,17 @@ MimeMessage::make_from_text(const std::string& text)
return make_from_stream(std::move(stream)); return make_from_stream(std::move(stream));
} }
Option<int64_t> Option<MimeMessage::Date>
MimeMessage::date() const noexcept MimeMessage::date() const noexcept
{ {
if (/*const*/GDateTime *dt{g_mime_message_get_date(self())}; !dt) if (/*const*/GDateTime *dt{g_mime_message_get_date(self())}; !dt)
return Nothing; return Nothing;
else else {
return g_date_time_to_unix(dt); constexpr auto usecs_per_sec = 1'000'000;
return Date{ g_date_time_to_unix(dt),
g_date_time_get_utc_offset(dt) / usecs_per_sec };
}
} }
constexpr Option<GMimeAddressType> constexpr Option<GMimeAddressType>
@ -431,7 +435,8 @@ MimeMessage::contacts(Contact::Type ctype) const noexcept
return {}; return {};
Contacts contacts; Contacts contacts;
add_contacts(addrs, ctype, date().value_or(0), contacts); const auto mdate{date()};
add_contacts(addrs, ctype, mdate ? mdate->first : 0, contacts);
return contacts; return contacts;
} }

View File

@ -1047,12 +1047,19 @@ public:
return Mu::to_string_opt(g_mime_message_get_subject(self())); return Mu::to_string_opt(g_mime_message_get_subject(self()));
} }
using Date = std::pair<int64_t/*unix-time*/, int64_t/*utc-offset in secs*/>;
/**< Date type */
/** /**
* Gets the date if it exists, or nullopt otherwise. * Gets a date, utf-offset pair if it exists, or nullopt otherwise.
*
* The date is the number of seconds since epoch (i.e., unix time),
* while utf-offset is the number of seconds offset from UTC
* (i.e., negative numbers west of GMT, positive numbers for east)
* *
* @return a time_t value (expressed as a 64-bit number) or nullopt * @return a time_t value (expressed as a 64-bit number) or nullopt
*/ */
Option<int64_t> date() const noexcept; Option<Date> date() const noexcept;
/** /**

View File

@ -307,7 +307,7 @@ test_view_sexp()
g_assert_true(::stat(msgpath.c_str(), &statbuf) == 0); g_assert_true(::stat(msgpath.c_str(), &statbuf) == 0);
const auto expected = mu_format( const auto expected = mu_format(
R"((:path "{}" :size 638 :changed ({} {} 0) :date (19930 8345 0) :flags (unread) :from ((:email "test@example.com" :name "Test")) :message-id "10374608.109906.11909.20115aabbccdd.MSGID@mailinglijst.nl" :priority normal :subject "vla" :to ((:email "abc@example.com"))) R"((:path "{}" :size 638 :changed ({} {} 0) :date (19930 8345 0) :utc-offset 7200 :flags (unread) :from ((:email "test@example.com" :name "Test")) :message-id "10374608.109906.11909.20115aabbccdd.MSGID@mailinglijst.nl" :priority normal :subject "vla" :to ((:email "abc@example.com")))
)", )",
msgpath, msgpath,
statbuf.st_ctime >> 16, statbuf.st_ctime >> 16,