From ee4b3bda2dc627cc695c211de2e91a2d347cb827 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sun, 1 May 2022 11:18:57 +0300 Subject: [PATCH] message: support 'personal' flag for messages Add a new flag 'personal' for a message, which means that at least one of the contact fields is personal. --- lib/message/mu-flags.cc | 2 +- lib/message/mu-flags.hh | 14 ++++++++++---- lib/mu-contacts-cache.cc | 4 ++-- lib/mu-contacts-cache.hh | 9 ++++++++- lib/mu-store.cc | 14 ++++++++++++-- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/message/mu-flags.cc b/lib/message/mu-flags.cc index fc45f52c..731e0562 100644 --- a/lib/message/mu-flags.cc +++ b/lib/message/mu-flags.cc @@ -166,7 +166,7 @@ test_flag_info() { static_assert(flag_info('D')->flag == Flags::Draft); static_assert(flag_info('l')->flag == Flags::MailingList); - static_assert(!flag_info('q')); + static_assert(!flag_info('y')); static_assert(flag_info("trashed")->flag == Flags::Trashed); static_assert(flag_info("attach")->flag == Flags::HasAttachment); diff --git a/lib/message/mu-flags.hh b/lib/message/mu-flags.hh index 637bc4a6..9bb7b177 100644 --- a/lib/message/mu-flags.hh +++ b/lib/message/mu-flags.hh @@ -63,11 +63,12 @@ enum struct Flags { * other content flags */ MailingList = 1 << 11, /**< A mailing-list message */ - + Personal = 1 << 12, /**< A personal message (i.e., at least one of the + * contact fields contains a personal address) */ /* * */ - _final_ = 1 << 12 + _final_ = 1 << 13 }; MU_ENABLE_BITOPS(Flags); @@ -90,7 +91,9 @@ enum struct MessageFlagCategory { struct MessageFlagInfo { Flags flag; /**< The message flag */ - char shortcut; /**< Shortcut character */ + char shortcut; /**< Shortcut character; + * tolower(shortcut) must be + * unique for all flags */ std::string_view name; /**< Name of the flag */ MessageFlagCategory category; /**< Flag category */ std::string_view description; /**< Description */ @@ -109,7 +112,7 @@ struct MessageFlagInfo { /** * Array of all flag information. */ -constexpr std::array AllMessageFlagInfos = {{ +constexpr std::array AllMessageFlagInfos = {{ MessageFlagInfo{Flags::Draft, 'D', "draft", MessageFlagCategory::Mailfile, "Draft (in progress)" }, @@ -147,6 +150,9 @@ constexpr std::array AllMessageFlagInfos = {{ MessageFlagInfo{Flags::MailingList, 'l', "list", MessageFlagCategory::Content, "Mailing list message" }, + MessageFlagInfo{Flags::Personal, 'q', "personal", MessageFlagCategory::Content, + "Personal message" + }, }}; diff --git a/lib/mu-contacts-cache.cc b/lib/mu-contacts-cache.cc index 0cc4e9ca..8d68af13 100644 --- a/lib/mu-contacts-cache.cc +++ b/lib/mu-contacts-cache.cc @@ -221,9 +221,9 @@ ContactsCache::add(Contact&& contact) void -ContactsCache::add(Contacts&& contacts) +ContactsCache::add(Contacts&& contacts, bool& personal) { - const auto personal = seq_find_if(contacts,[&](auto&& c){ + personal = seq_find_if(contacts,[&](auto&& c){ return is_personal(c.email); }) != contacts.cend(); for (auto&& contact: contacts) { diff --git a/lib/mu-contacts-cache.hh b/lib/mu-contacts-cache.hh index b80cadc1..a80260c8 100644 --- a/lib/mu-contacts-cache.hh +++ b/lib/mu-contacts-cache.hh @@ -66,8 +66,15 @@ public: * any of the senders/recipients are considered "personal" * * @param contacts a Contact object sequence + * @param is_personal receives true if any of the contacts was personal; + * false otherwise */ - void add(Contacts&& contacts); + void add(Contacts&& contacts, bool& is_personal); + void add(Contacts&& contacts) { + bool _ignore; + add(std::move(contacts), _ignore); + } + /** * Clear all contacts diff --git a/lib/mu-store.cc b/lib/mu-store.cc index ffbed1d8..28725d1e 100644 --- a/lib/mu-store.cc +++ b/lib/mu-store.cc @@ -344,14 +344,24 @@ Store::add_message(Message& msg, bool use_transaction) if (auto&& res = msg.set_maildir(mdir.value()); !res) return Err(res.error()); + /* add contacts from this message to cache; this cache + * also determines whether those contacts are _personal_, i.e. match + * our personal addresses. + * + * if a message has any personal contacts, mark it as personal; do + * this by updating the message flags. + */ + bool is_personal{}; + priv_->contacts_cache_.add(msg.all_contacts(), is_personal); + if (is_personal) + msg.set_flags(msg.flags() | Flags::Personal); + /* now, we're done with all the fields; generate the sexp string for this * message */ msg.update_cached_sexp(); std::lock_guard guard{priv_->lock_}; - priv_->contacts_cache_.add(msg.all_contacts()); - const auto docid = xapian_try([&]{ if (use_transaction)