message: contact: remove ::Type, use Field
Don't need a special Type {} in Contact, when we have more-or-less the same info
in Field.
This commit is contained in:
@ -18,11 +18,13 @@
|
||||
*/
|
||||
|
||||
#include "mu-message-contact.hh"
|
||||
#include "mu-message.hh"
|
||||
|
||||
#include <gmime/gmime.h>
|
||||
#include <glib.h>
|
||||
|
||||
using namespace Mu;
|
||||
|
||||
using namespace Mu::Message;
|
||||
|
||||
std::string
|
||||
MessageContact::display_name() const
|
||||
@ -35,8 +37,7 @@ MessageContact::display_name() const
|
||||
|
||||
Mu::MessageContacts
|
||||
Mu::make_message_contacts(InternetAddressList* addr_lst,
|
||||
MessageContact::Type type,
|
||||
::time_t message_date)
|
||||
Field::Id field_id, ::time_t message_date)
|
||||
{
|
||||
MessageContacts contacts;
|
||||
size_t num{};
|
||||
@ -59,7 +60,7 @@ Mu::make_message_contacts(InternetAddressList* addr_lst,
|
||||
continue;
|
||||
|
||||
contacts.push_back(MessageContact{email, name ? name : "",
|
||||
type, message_date});
|
||||
field_id, message_date});
|
||||
++num;
|
||||
}
|
||||
|
||||
@ -69,7 +70,7 @@ Mu::make_message_contacts(InternetAddressList* addr_lst,
|
||||
|
||||
Mu::MessageContacts
|
||||
Mu::make_message_contacts(const std::string& addrs,
|
||||
MessageContact::Type type,
|
||||
Field::Id field_id,
|
||||
::time_t message_date)
|
||||
{
|
||||
auto addr_list = internet_address_list_parse(NULL, addrs.c_str());
|
||||
@ -78,7 +79,7 @@ Mu::make_message_contacts(const std::string& addrs,
|
||||
return {};
|
||||
}
|
||||
|
||||
auto contacts{make_message_contacts(addr_list, type, message_date)};
|
||||
auto contacts{make_message_contacts(addr_list, field_id, message_date)};
|
||||
g_object_unref(addr_list);
|
||||
|
||||
return contacts;
|
||||
@ -109,13 +110,13 @@ test_ctor_foo()
|
||||
MessageContact c{
|
||||
"foo@example.com",
|
||||
"Foo Bar",
|
||||
MessageContact::Type::Bcc,
|
||||
Field::Id::Bcc,
|
||||
1645214647
|
||||
};
|
||||
|
||||
assert_equal(c.email, "foo@example.com");
|
||||
assert_equal(c.name, "Foo Bar");
|
||||
g_assert_true(c.type == MessageContact::Type::Bcc);
|
||||
g_assert_true(c.field_id == Field::Id::Bcc);
|
||||
g_assert_cmpuint(c.message_date,==,1645214647);
|
||||
|
||||
assert_equal(c.display_name(), "Foo Bar <foo@example.com>");
|
||||
@ -178,12 +179,12 @@ test_make_contacts()
|
||||
internet_address_list_parse(NULL, str)};
|
||||
|
||||
g_assert_true(lst);
|
||||
const auto addrs{make_message_contacts(lst, MessageContact::Type::Cc, 54321 )};
|
||||
const auto addrs{make_message_contacts(lst, Field::Id::Cc, 54321 )};
|
||||
g_object_unref(lst);
|
||||
|
||||
g_assert_cmpuint(addrs.size(),==,3);
|
||||
|
||||
const auto addrs2{make_message_contacts(str, MessageContact::Type::To, 12345 )};
|
||||
const auto addrs2{make_message_contacts(str, Field::Id::To, 12345 )};
|
||||
g_assert_cmpuint(addrs2.size(),==,3);
|
||||
|
||||
assert_equal(addrs2[0].name, "Abc");
|
||||
@ -201,7 +202,7 @@ test_make_contacts_2()
|
||||
"De\nf <baa@example.com>, "
|
||||
"\tGhi <zzz@example.com>";
|
||||
|
||||
const auto addrs2{make_message_contacts(str, MessageContact::Type::Bcc, 12345 )};
|
||||
const auto addrs2{make_message_contacts(str, Field::Id::Bcc, 12345 )};
|
||||
g_assert_cmpuint(addrs2.size(),==,3);
|
||||
|
||||
assert_equal(addrs2[0].name, "Äbc");
|
||||
@ -221,7 +222,7 @@ test_make_contacts_err()
|
||||
InternetAddressList *lst{ internet_address_list_parse(NULL, "")};
|
||||
g_assert_false(lst);
|
||||
|
||||
const auto addrs{make_message_contacts("", MessageContact::Type::To, 77777)};
|
||||
const auto addrs{make_message_contacts("", Field::Id::To, 77777)};
|
||||
g_assert_true(addrs.empty());
|
||||
}
|
||||
|
||||
|
||||
@ -44,31 +44,19 @@ namespace Mu {
|
||||
*/
|
||||
size_t lowercase_hash(const std::string& s);
|
||||
|
||||
|
||||
struct MessageContact {
|
||||
/**
|
||||
* Contact types
|
||||
*/
|
||||
enum struct Type {
|
||||
To, /**< To recipient */
|
||||
From, /**< Sender */
|
||||
Cc, /**< Cc recipient */
|
||||
Bcc, /**< Bcc recipient */
|
||||
ReplyTo, /**< Reply-To wannabe recipient */
|
||||
Unknown, /**< Unknown type */
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a new MessageContact
|
||||
*
|
||||
* @param email_ email address
|
||||
* @param name_ name or empty
|
||||
* @param type_ contact type
|
||||
* @param field_id_ contact field id, or {}
|
||||
* @param message_date_ data for the message for this contact
|
||||
*/
|
||||
MessageContact(const std::string& email_, const std::string& name_ = "",
|
||||
Type type_ = Type::Unknown, time_t message_date_ = 0)
|
||||
: email{email_}, name{name_}, type{type_},
|
||||
std::optional<MessageField::Id> field_id_ = {},
|
||||
time_t message_date_ = 0)
|
||||
: email{email_}, name{name_}, field_id{field_id_},
|
||||
message_date{message_date_}, personal{}, frequency{1}, tstamp{}
|
||||
{ cleanup_name(); }
|
||||
|
||||
@ -85,7 +73,7 @@ struct MessageContact {
|
||||
MessageContact(const std::string& email_, const std::string& name_,
|
||||
time_t message_date_, bool personal_, size_t freq_,
|
||||
int64_t tstamp_)
|
||||
: email{email_}, name{name_}, type{Type::Unknown},
|
||||
: email{email_}, name{name_}, field_id{},
|
||||
message_date{message_date_}, personal{personal_}, frequency{freq_},
|
||||
tstamp{tstamp_}
|
||||
{ cleanup_name();}
|
||||
@ -126,39 +114,18 @@ struct MessageContact {
|
||||
return cached_hash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the MessageField for this contact-type, if any.
|
||||
*
|
||||
* @return the message-field or nullopt.
|
||||
*/
|
||||
constexpr std::optional<MessageField> const field() {
|
||||
switch(type){
|
||||
case Type::From:
|
||||
return message_field(MessageField::Id::From);
|
||||
case Type::To:
|
||||
return message_field(MessageField::Id::To);
|
||||
case Type::Cc:
|
||||
return message_field(MessageField::Id::Cc);
|
||||
case Type::Bcc:
|
||||
return message_field(MessageField::Id::Bcc);
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* data members
|
||||
*/
|
||||
|
||||
std::string email; /**< Email address for this contact.Not empty */
|
||||
std::string name; /**< Name for this contact; can be empty. */
|
||||
Type type{Type::Unknown}; /**< Type of contact */
|
||||
::time_t message_date; /**< date of the message from which the
|
||||
* contact originates */
|
||||
bool personal; /**< A personal message? */
|
||||
size_t frequency; /**< Frequency of this contact */
|
||||
int64_t tstamp; /**< Timestamp for this contact */
|
||||
std::string email; /**< Email address for this contact.Not empty */
|
||||
std::string name; /**< Name for this contact; can be empty. */
|
||||
std::optional<MessageField::Id> field_id; /**< Field Id of contact or nullopt */
|
||||
::time_t message_date; /**< date of the message from which the
|
||||
* contact originates */
|
||||
bool personal; /**< A personal message? */
|
||||
size_t frequency; /**< Frequency of this contact */
|
||||
int64_t tstamp; /**< Timestamp for this contact */
|
||||
|
||||
private:
|
||||
void cleanup_name() { // replace control characters by spaces.
|
||||
@ -174,7 +141,7 @@ using MessageContacts = std::vector<MessageContact>;
|
||||
* Create a sequence of MessageContact objects from an InternetAddressList
|
||||
*
|
||||
* @param addr_lst an address list
|
||||
* @param type the type of addresses
|
||||
* @param field_id the field_id for message field for these addresses
|
||||
* @param message_date the date of the message from which the InternetAddressList
|
||||
* originates.
|
||||
*
|
||||
@ -182,20 +149,20 @@ using MessageContacts = std::vector<MessageContact>;
|
||||
*/
|
||||
MessageContacts
|
||||
make_message_contacts(/*const*/ struct _InternetAddressList* addr_lst,
|
||||
MessageContact::Type type, ::time_t message_date);
|
||||
MessageField::Id field_id, ::time_t message_date);
|
||||
|
||||
/**
|
||||
* Create a sequence of MessageContact objects from an InternetAddressList
|
||||
*
|
||||
* @param addrs a string with one more valid addresses (as per internet_address_list_parse())
|
||||
* @param type the type of addresses
|
||||
* @param field_id the field_id for message field for these addresses
|
||||
* @param message_date the date of the message from which the addresses originate
|
||||
*
|
||||
* @return a sequence of MessageContact objects.
|
||||
*/
|
||||
MessageContacts
|
||||
make_message_contacts(const std::string& addrs,
|
||||
MessageContact::Type type, ::time_t message_date);
|
||||
MessageField::Id field_id, ::time_t message_date);
|
||||
} // namespace Mu
|
||||
|
||||
/**
|
||||
@ -207,7 +174,4 @@ template<> struct std::hash<Mu::MessageContact> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* MU_MESSAGE_CONTACT_HH__ */
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mu-message-flags.hh"
|
||||
#include "mu-message.hh"
|
||||
#include "mu-query-results.hh"
|
||||
#include "utils/mu-str.h"
|
||||
#include "mu-msg.hh"
|
||||
@ -27,6 +27,7 @@
|
||||
#include "mu-maildir.hh"
|
||||
|
||||
using namespace Mu;
|
||||
using namespace Mu::Message;
|
||||
|
||||
static void
|
||||
add_prop_nonempty(Sexp::List& list, const char* elm, const GSList* str_lst)
|
||||
@ -76,9 +77,9 @@ add_list_post(Sexp::List& list, MuMsg* msg)
|
||||
return;
|
||||
|
||||
rx = g_regex_new("<?mailto:([a-z0-9!@#$%&'*+-/=?^_`{|}~]+)>?",
|
||||
G_REGEX_CASELESS,
|
||||
(GRegexMatchFlags)0,
|
||||
NULL);
|
||||
G_REGEX_CASELESS,
|
||||
(GRegexMatchFlags)0,
|
||||
NULL);
|
||||
g_return_if_fail(rx);
|
||||
|
||||
if (g_regex_match(rx, list_post, (GRegexMatchFlags)0, &minfo)) {
|
||||
@ -94,22 +95,22 @@ add_list_post(Sexp::List& list, MuMsg* msg)
|
||||
static void
|
||||
add_contacts(Sexp::List& list, MuMsg* msg)
|
||||
{
|
||||
using ContactPair = std::pair<MessageContact::Type, std::string_view>;
|
||||
using ContactPair = std::pair<Field::Id, std::string_view>;
|
||||
constexpr std::array<ContactPair, 5> contact_types = {{
|
||||
{ MessageContact::Type::From, ":from" },
|
||||
{ MessageContact::Type::To, ":to" },
|
||||
{ MessageContact::Type::Cc, ":cc" },
|
||||
{ MessageContact::Type::ReplyTo, ":reply-to" },
|
||||
{ MessageContact::Type::Bcc, ":bcc" },
|
||||
{ Field::Id::From, ":from" },
|
||||
{ Field::Id::To, ":to" },
|
||||
{ Field::Id::Cc, ":cc" },
|
||||
// { Field::Id::ReplyTo, ":reply-to" },
|
||||
{ Field::Id::Bcc, ":bcc" },
|
||||
}};
|
||||
|
||||
|
||||
for (auto&& contact_type : contact_types) {
|
||||
|
||||
|
||||
const auto contacts{mu_msg_get_contacts(msg, contact_type.first)};
|
||||
if (contacts.empty())
|
||||
continue;
|
||||
|
||||
Sexp::List c_list;
|
||||
Sexp::List c_list;
|
||||
for (auto&& contact: contacts)
|
||||
c_list.add(make_contact_sexp(contact));
|
||||
|
||||
@ -151,7 +152,7 @@ get_temp_file(MuMsg* msg, MuMsgOptions opts, unsigned index)
|
||||
|
||||
errexit:
|
||||
g_warning("failed to save mime part: %s",
|
||||
err->message ? err->message : "something went wrong");
|
||||
err->message ? err->message : "something went wrong");
|
||||
g_clear_error(&err);
|
||||
g_free(path);
|
||||
|
||||
@ -216,11 +217,11 @@ make_part_types(MuMsgPartType ptype)
|
||||
MuMsgPartType ptype;
|
||||
const char* name;
|
||||
} ptypes[] = {{MU_MSG_PART_TYPE_LEAF, "leaf"},
|
||||
{MU_MSG_PART_TYPE_MESSAGE, "message"},
|
||||
{MU_MSG_PART_TYPE_INLINE, "inline"},
|
||||
{MU_MSG_PART_TYPE_ATTACHMENT, "attachment"},
|
||||
{MU_MSG_PART_TYPE_SIGNED, "signed"},
|
||||
{MU_MSG_PART_TYPE_ENCRYPTED, "encrypted"}};
|
||||
{MU_MSG_PART_TYPE_MESSAGE, "message"},
|
||||
{MU_MSG_PART_TYPE_INLINE, "inline"},
|
||||
{MU_MSG_PART_TYPE_ATTACHMENT, "attachment"},
|
||||
{MU_MSG_PART_TYPE_SIGNED, "signed"},
|
||||
{MU_MSG_PART_TYPE_ENCRYPTED, "encrypted"}};
|
||||
|
||||
Sexp::List list;
|
||||
for (auto u = 0U; u != G_N_ELEMENTS(ptypes); ++u)
|
||||
@ -234,8 +235,8 @@ static void
|
||||
each_part(MuMsg* msg, MuMsgPart* part, PartInfo* pinfo)
|
||||
{
|
||||
auto mimetype = format("%s/%s",
|
||||
part->type ? part->type : "application",
|
||||
part->subtype ? part->subtype : "octet-stream");
|
||||
part->type ? part->type : "application",
|
||||
part->subtype ? part->subtype : "octet-stream");
|
||||
auto maybe_attach = Sexp::make_symbol(mu_msg_part_maybe_attachment(part) ? "t" : "nil");
|
||||
Sexp::List partlist;
|
||||
|
||||
@ -285,7 +286,7 @@ add_message_file_parts(Sexp::List& items, MuMsg* msg, MuMsgOptions opts)
|
||||
GError* err{NULL};
|
||||
if (!mu_msg_load_msg_file(msg, &err)) {
|
||||
g_warning("failed to load message file: %s",
|
||||
err ? err->message : "some error occurred");
|
||||
err ? err->message : "some error occurred");
|
||||
g_clear_error(&err);
|
||||
return;
|
||||
}
|
||||
@ -301,8 +302,8 @@ add_message_file_parts(Sexp::List& items, MuMsg* msg, MuMsgOptions opts)
|
||||
add_prop_nonempty(items, ":user-agent", str);
|
||||
|
||||
add_prop_nonempty(items,
|
||||
":body-txt-params",
|
||||
mu_msg_get_body_text_content_type_parameters(msg, opts));
|
||||
":body-txt-params",
|
||||
mu_msg_get_body_text_content_type_parameters(msg, opts));
|
||||
add_prop_nonempty(items, ":body-txt", mu_msg_get_body_text(msg, opts));
|
||||
add_prop_nonempty(items, ":body-html", mu_msg_get_body_html(msg, opts));
|
||||
}
|
||||
@ -358,7 +359,7 @@ Mu::msg_to_sexp_list(MuMsg* msg, unsigned docid, MuMsgOptions opts)
|
||||
add_prop_nonempty(items, ":maildir", mu_msg_get_maildir(msg));
|
||||
|
||||
items.add_prop(":priority",
|
||||
Sexp::make_symbol_sv(message_priority_name(mu_msg_get_prio(msg))));
|
||||
Sexp::make_symbol_sv(message_priority_name(mu_msg_get_prio(msg))));
|
||||
|
||||
/* in the no-headers-only case (see below) we get a more complete list of contacts, so no
|
||||
* need to get them here if that's the case */
|
||||
|
||||
@ -624,40 +624,40 @@ get_all_contacts(MuMsg *self)
|
||||
{
|
||||
MessageContacts contacts;
|
||||
|
||||
for (auto&& mtype : { MessageContact::Type::From, MessageContact::Type::To,
|
||||
MessageContact::Type::Cc, MessageContact::Type::ReplyTo,
|
||||
MessageContact::Type::Bcc}) {
|
||||
auto type_contacts{mu_msg_get_contacts(self, mtype)};
|
||||
message_field_for_each([&](const auto& field){
|
||||
if (!field.is_contact())
|
||||
return;
|
||||
auto type_contacts{mu_msg_get_contacts(self, field.id)};
|
||||
|
||||
contacts.reserve(contacts.size() + type_contacts.size());
|
||||
contacts.insert(contacts.end(), type_contacts.begin(), type_contacts.end());
|
||||
}
|
||||
contacts.insert(contacts.end(), type_contacts.begin(),
|
||||
type_contacts.end());
|
||||
});
|
||||
|
||||
return contacts;
|
||||
}
|
||||
|
||||
Mu::MessageContacts
|
||||
Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
|
||||
Mu::mu_msg_get_contacts(MuMsg *self, std::optional<MessageField::Id> field_id)
|
||||
{
|
||||
typedef const char*(*AddressFunc)(MuMsg*);
|
||||
using AddressInfo = std::pair<GMimeAddressType, AddressFunc>;
|
||||
|
||||
g_return_val_if_fail(self, MessageContacts{});
|
||||
|
||||
if (mtype == MessageContact::Type::Unknown)
|
||||
g_return_val_if_fail(!field_id || message_field(*field_id).is_contact(),
|
||||
MessageContacts{});
|
||||
if (!field_id)
|
||||
return get_all_contacts(self);
|
||||
|
||||
const auto info = std::invoke([&]()->AddressInfo {
|
||||
switch (mtype) {
|
||||
case MessageContact::Type::From:
|
||||
switch (*field_id) {
|
||||
case MessageField::Id::From:
|
||||
return { GMIME_ADDRESS_TYPE_FROM, mu_msg_get_from };
|
||||
case MessageContact::Type::To:
|
||||
case MessageField::Id::To:
|
||||
return { GMIME_ADDRESS_TYPE_TO, mu_msg_get_to };
|
||||
case MessageContact::Type::Cc:
|
||||
case MessageField::Id::Cc:
|
||||
return { GMIME_ADDRESS_TYPE_CC, mu_msg_get_cc };
|
||||
case MessageContact::Type::ReplyTo:
|
||||
return { GMIME_ADDRESS_TYPE_REPLY_TO, {} };
|
||||
case MessageContact::Type::Bcc:
|
||||
case MessageField::Id::Bcc:
|
||||
return { GMIME_ADDRESS_TYPE_BCC, mu_msg_get_bcc };
|
||||
default:
|
||||
throw std::logic_error("bug");
|
||||
@ -668,10 +668,10 @@ Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
|
||||
if (self->_file) {
|
||||
if (auto&& lst{g_mime_message_get_addresses(
|
||||
self->_file->_mime_msg, info.first)}; lst)
|
||||
return make_message_contacts(lst, mtype, mdate);
|
||||
return make_message_contacts(lst, *field_id, mdate);
|
||||
} else if (info.second) {
|
||||
if (auto&& lst_str{info.second(self)}; lst_str)
|
||||
return make_message_contacts(lst_str, mtype, mdate);
|
||||
return make_message_contacts(lst_str, *field_id, mdate);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
@ -441,13 +441,12 @@ bool mu_msg_move_to_maildir(MuMsg* msg,
|
||||
* Get a sequence with contacts of the given type for this message.
|
||||
*
|
||||
* @param msg a valid MuMsg* instance
|
||||
* @param mtype the contact type; with Type::Unknown, get _all_ types.
|
||||
* @param field_id the contact field or none; if none get _all_ contact types.
|
||||
*
|
||||
* @return a sequence
|
||||
*/
|
||||
Mu::MessageContacts mu_msg_get_contacts (MuMsg *self,
|
||||
MessageContact::Type mtype=MessageContact::Type::Unknown);
|
||||
|
||||
std::optional<MessageField::Id> field_id={});
|
||||
/**
|
||||
* create a 'display contact' from an email header To/Cc/Bcc/From-type address
|
||||
* ie., turn
|
||||
|
||||
Reference in New Issue
Block a user