mirror of https://github.com/djcb/mu.git
contacts: expose contact type
Instead of the Field::Id, keep a specific Contact::Type so we can distinguish Sender, ReplyTo as well. Update dependents. Some cleanup.
This commit is contained in:
parent
561593c194
commit
263e122a13
|
@ -35,57 +35,6 @@ Contact::display_name() const
|
||||||
return name + " <" + email + '>';
|
return name + " <" + email + '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
Mu::Contacts
|
|
||||||
Mu::make_contacts(InternetAddressList* addr_lst,
|
|
||||||
Field::Id field_id, int64_t message_date)
|
|
||||||
{
|
|
||||||
Contacts contacts;
|
|
||||||
size_t num{};
|
|
||||||
|
|
||||||
g_return_val_if_fail(addr_lst, contacts);
|
|
||||||
|
|
||||||
auto lst_len{internet_address_list_length(addr_lst)};
|
|
||||||
contacts.reserve(lst_len);
|
|
||||||
for (auto i = 0; i != lst_len; ++i) {
|
|
||||||
|
|
||||||
auto&& addr{internet_address_list_get_address(addr_lst, i)};
|
|
||||||
const auto name{internet_address_get_name(addr)};
|
|
||||||
|
|
||||||
if (G_UNLIKELY(!INTERNET_ADDRESS_IS_MAILBOX(addr)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const auto email{internet_address_mailbox_get_addr (
|
|
||||||
INTERNET_ADDRESS_MAILBOX(addr))};
|
|
||||||
if (G_UNLIKELY(!email))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
contacts.push_back(Contact{email, name ? name : "",
|
|
||||||
field_id, message_date});
|
|
||||||
++num;
|
|
||||||
}
|
|
||||||
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Mu::Contacts
|
|
||||||
Mu::make_contacts(const std::string& addrs,
|
|
||||||
Field::Id field_id,
|
|
||||||
int64_t message_date)
|
|
||||||
{
|
|
||||||
auto addr_list = internet_address_list_parse(NULL, addrs.c_str());
|
|
||||||
if (!addr_list) {
|
|
||||||
g_warning("no addresses found in '%s'", addrs.c_str());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto contacts{make_contacts(addr_list, field_id, message_date)};
|
|
||||||
g_object_unref(addr_list);
|
|
||||||
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Mu::to_string(const Mu::Contacts& contacts)
|
Mu::to_string(const Mu::Contacts& contacts)
|
||||||
{
|
{
|
||||||
|
@ -125,13 +74,13 @@ test_ctor_foo()
|
||||||
Contact c{
|
Contact c{
|
||||||
"foo@example.com",
|
"foo@example.com",
|
||||||
"Foo Bar",
|
"Foo Bar",
|
||||||
Field::Id::Bcc,
|
Contact::Type::Bcc,
|
||||||
1645214647
|
1645214647
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_equal(c.email, "foo@example.com");
|
assert_equal(c.email, "foo@example.com");
|
||||||
assert_equal(c.name, "Foo Bar");
|
assert_equal(c.name, "Foo Bar");
|
||||||
g_assert_true(c.field_id == Field::Id::Bcc);
|
g_assert_true(*c.field_id() == Field::Id::Bcc);
|
||||||
g_assert_cmpuint(c.message_date,==,1645214647);
|
g_assert_cmpuint(c.message_date,==,1645214647);
|
||||||
|
|
||||||
assert_equal(c.display_name(), "Foo Bar <foo@example.com>");
|
assert_equal(c.display_name(), "Foo Bar <foo@example.com>");
|
||||||
|
@ -183,64 +132,6 @@ test_ctor_cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_make_contacts()
|
|
||||||
{
|
|
||||||
const auto str = "Abc <boo@example.com>, "
|
|
||||||
"Def <baa@example.com>, "
|
|
||||||
"Ghi <zzz@example.com>";
|
|
||||||
InternetAddressList *lst{
|
|
||||||
internet_address_list_parse(NULL, str)};
|
|
||||||
|
|
||||||
g_assert_true(lst);
|
|
||||||
const auto addrs{make_contacts(lst, Field::Id::Cc, 54321 )};
|
|
||||||
g_object_unref(lst);
|
|
||||||
|
|
||||||
g_assert_cmpuint(addrs.size(),==,3);
|
|
||||||
|
|
||||||
const auto addrs2{make_contacts(str, Field::Id::To, 12345 )};
|
|
||||||
g_assert_cmpuint(addrs2.size(),==,3);
|
|
||||||
|
|
||||||
assert_equal(addrs2[0].name, "Abc");
|
|
||||||
assert_equal(addrs2[0].email, "boo@example.com");
|
|
||||||
assert_equal(addrs2[1].name, "Def");
|
|
||||||
assert_equal(addrs2[1].email, "baa@example.com");
|
|
||||||
assert_equal(addrs2[2].name, "Ghi");
|
|
||||||
assert_equal(addrs2[2].email, "zzz@example.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_make_contacts_2()
|
|
||||||
{
|
|
||||||
const auto str = "Äbc <boo@example.com>, "
|
|
||||||
"De\nf <baa@example.com>, "
|
|
||||||
"\tGhi <zzz@example.com>";
|
|
||||||
|
|
||||||
const auto addrs2{make_contacts(str, Field::Id::Bcc, 12345 )};
|
|
||||||
g_assert_cmpuint(addrs2.size(),==,3);
|
|
||||||
|
|
||||||
assert_equal(addrs2[0].name, "Äbc");
|
|
||||||
assert_equal(addrs2[0].email, "boo@example.com");
|
|
||||||
assert_equal(addrs2[1].name, "De f");
|
|
||||||
assert_equal(addrs2[1].email, "baa@example.com");
|
|
||||||
assert_equal(addrs2[2].name, "Ghi");
|
|
||||||
assert_equal(addrs2[2].email, "zzz@example.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_make_contacts_err()
|
|
||||||
{
|
|
||||||
allow_warnings();
|
|
||||||
|
|
||||||
InternetAddressList *lst{ internet_address_list_parse(NULL, "")};
|
|
||||||
g_assert_false(lst);
|
|
||||||
|
|
||||||
const auto addrs{make_contacts("", Field::Id::To, 77777)};
|
|
||||||
g_assert_true(addrs.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char* argv[])
|
main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -250,9 +141,6 @@ main(int argc, char* argv[])
|
||||||
g_test_add_func("/message/contact/ctor-foo", test_ctor_foo);
|
g_test_add_func("/message/contact/ctor-foo", test_ctor_foo);
|
||||||
g_test_add_func("/message/contact/ctor-blinky", test_ctor_blinky);
|
g_test_add_func("/message/contact/ctor-blinky", test_ctor_blinky);
|
||||||
g_test_add_func("/message/contact/ctor-cleanup", test_ctor_cleanup);
|
g_test_add_func("/message/contact/ctor-cleanup", test_ctor_cleanup);
|
||||||
g_test_add_func("/message/contact/make-contacts", test_make_contacts);
|
|
||||||
g_test_add_func("/message/contact/make-contacts-2", test_make_contacts_2);
|
|
||||||
g_test_add_func("/message/contact/make-contacts-err", test_make_contacts_err);
|
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,19 +46,22 @@ namespace Mu {
|
||||||
size_t lowercase_hash(const std::string& s);
|
size_t lowercase_hash(const std::string& s);
|
||||||
|
|
||||||
struct Contact {
|
struct Contact {
|
||||||
|
enum struct Type {
|
||||||
|
None, Sender, From, ReplyTo, To, Cc, Bcc
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new Contact
|
* Construct a new Contact
|
||||||
*
|
*
|
||||||
* @param email_ email address
|
* @param email_ email address
|
||||||
* @param name_ name or empty
|
* @param name_ name or empty
|
||||||
* @param field_id_ contact field id, or {}
|
* @param type_ contact field type
|
||||||
* @param message_date_ data for the message for this contact
|
* @param message_date_ data for the message for this contact
|
||||||
*/
|
*/
|
||||||
Contact(const std::string& email_, const std::string& name_ = "",
|
Contact(const std::string& email_, const std::string& name_ = "",
|
||||||
Option<Field::Id> field_id_ = {},
|
Type type_ = Type::None, ::time_t message_date_ = 0)
|
||||||
time_t message_date_ = 0)
|
: email{email_}, name{name_}, type{type_},
|
||||||
: email{email_}, name{name_}, field_id{field_id_},
|
message_date{message_date_}, personal{}, frequency{1}, tstamp{}
|
||||||
message_date{message_date_}, personal{}, frequency{1}, tstamp{}
|
|
||||||
{ cleanup_name(); }
|
{ cleanup_name(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +77,7 @@ struct Contact {
|
||||||
Contact(const std::string& email_, const std::string& name_,
|
Contact(const std::string& email_, const std::string& name_,
|
||||||
time_t message_date_, bool personal_, size_t freq_,
|
time_t message_date_, bool personal_, size_t freq_,
|
||||||
int64_t tstamp_)
|
int64_t tstamp_)
|
||||||
: email{email_}, name{name_}, field_id{},
|
: email{email_}, name{name_}, type{Type::None},
|
||||||
message_date{message_date_}, personal{personal_}, frequency{freq_},
|
message_date{message_date_}, personal{personal_}, frequency{freq_},
|
||||||
tstamp{tstamp_}
|
tstamp{tstamp_}
|
||||||
{ cleanup_name();}
|
{ cleanup_name();}
|
||||||
|
@ -115,18 +118,39 @@ struct Contact {
|
||||||
return cached_hash;
|
return cached_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the corresponding Field::Id (if any)
|
||||||
|
* for this contact.
|
||||||
|
*
|
||||||
|
* @return the field-id or Nothing.
|
||||||
|
*/
|
||||||
|
constexpr Option<Field::Id> field_id() const noexcept {
|
||||||
|
switch(type) {
|
||||||
|
case Type::Bcc:
|
||||||
|
return Field::Id::Bcc;
|
||||||
|
case Type::Cc:
|
||||||
|
return Field::Id::Cc;
|
||||||
|
case Type::From:
|
||||||
|
return Field::Id::From;
|
||||||
|
case Type::To:
|
||||||
|
return Field::Id::To;
|
||||||
|
default:
|
||||||
|
return Nothing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* data members
|
* data members
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::string email; /**< Email address for this contact.Not empty */
|
std::string email; /**< Email address for this contact.Not empty */
|
||||||
std::string name; /**< Name for this contact; can be empty. */
|
std::string name; /**< Name for this contact; can be empty. */
|
||||||
Option<Field::Id> field_id; /**< Field Id of contact or nullopt */
|
Type type; /**< Type of contact */
|
||||||
int64_t message_date; /**< date of the message from which the
|
int64_t message_date; /**< date of the contact's message */
|
||||||
* contact originates (or 0) */
|
|
||||||
bool personal; /**< A personal message? */
|
bool personal; /**< A personal message? */
|
||||||
size_t frequency; /**< Frequency of this contact */
|
size_t frequency; /**< Frequency of this contact */
|
||||||
int64_t tstamp; /**< Timestamp for this contact (internal use) */
|
int64_t tstamp; /**< Timestamp for this contact (internal use) */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cleanup_name() { // replace control characters by spaces.
|
void cleanup_name() { // replace control characters by spaces.
|
||||||
|
@ -136,35 +160,27 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
constexpr Option<Contact::Type>
|
||||||
|
contact_type_from_field_id(Field::Id id) noexcept {
|
||||||
|
|
||||||
|
switch(id) {
|
||||||
|
case Field::Id::Bcc:
|
||||||
|
return Contact::Type::Bcc;
|
||||||
|
case Field::Id::Cc:
|
||||||
|
return Contact::Type::Cc;
|
||||||
|
case Field::Id::From:
|
||||||
|
return Contact::Type::From;
|
||||||
|
case Field::Id::To:
|
||||||
|
return Contact::Type::To;
|
||||||
|
default:
|
||||||
|
return Nothing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
using Contacts = std::vector<Contact>;
|
using Contacts = std::vector<Contact>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a sequence of Contact objects from an InternetAddressList
|
|
||||||
*
|
|
||||||
* @param addr_lst an address list
|
|
||||||
* @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.
|
|
||||||
*
|
|
||||||
* @return a sequence of Contact objects.
|
|
||||||
*/
|
|
||||||
Contacts
|
|
||||||
make_contacts(/*const*/ struct _InternetAddressList* addr_lst,
|
|
||||||
Field::Id field_id, int64_t message_date);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a sequence of Contact objects from an InternetAddressList
|
|
||||||
*
|
|
||||||
* @param addrs a string with one more valid addresses (as per internet_address_list_parse())
|
|
||||||
* @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 Contact objects.
|
|
||||||
*/
|
|
||||||
Contacts
|
|
||||||
make_contacts(const std::string& addrs,
|
|
||||||
Field::Id field_id, int64_t message_date);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get contacts as a comma-separated list.
|
* Get contacts as a comma-separated list.
|
||||||
|
|
|
@ -107,7 +107,8 @@ Document::add(Field::Id id, const Contacts& contacts)
|
||||||
|
|
||||||
for (auto&& contact: contacts) {
|
for (auto&& contact: contacts) {
|
||||||
|
|
||||||
if (!contact.field_id || *contact.field_id != id)
|
const auto cfield_id{contact.field_id()};
|
||||||
|
if (!cfield_id || *cfield_id != id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xdoc_.add_term(field.xapian_term(contact.email));
|
xdoc_.add_term(field.xapian_term(contact.email));
|
||||||
|
@ -130,6 +131,13 @@ Document::contacts_value(Field::Id id) const noexcept
|
||||||
Contacts contacts;
|
Contacts contacts;
|
||||||
contacts.reserve(vals.size());
|
contacts.reserve(vals.size());
|
||||||
|
|
||||||
|
const auto ctype{contact_type_from_field_id(id)};
|
||||||
|
if (G_UNLIKELY(!ctype)) {
|
||||||
|
g_critical("invalid field-id for contact-type: <%zu>",
|
||||||
|
static_cast<size_t>(id));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
for (auto&& s: vals) {
|
for (auto&& s: vals) {
|
||||||
|
|
||||||
const auto pos = s.find(SepaChar2);
|
const auto pos = s.find(SepaChar2);
|
||||||
|
@ -138,7 +146,7 @@ Document::contacts_value(Field::Id id) const noexcept
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
contacts.emplace_back(s.substr(0, pos), s.substr(pos + 1), id);
|
contacts.emplace_back(s.substr(0, pos), s.substr(pos + 1), *ctype);
|
||||||
}
|
}
|
||||||
|
|
||||||
return contacts;
|
return contacts;
|
||||||
|
@ -223,14 +231,14 @@ Document::flags_value() const noexcept
|
||||||
|
|
||||||
|
|
||||||
static const Contacts test_contacts = {{
|
static const Contacts test_contacts = {{
|
||||||
Contact{"john@example.com", "John", Field::Id::Bcc},
|
Contact{"john@example.com", "John", Contact::Type::Bcc},
|
||||||
Contact{"ringo@example.com", "Ringo", Field::Id::Bcc},
|
Contact{"ringo@example.com", "Ringo", Contact::Type::Bcc},
|
||||||
Contact{"paul@example.com", "Paul", Field::Id::Cc},
|
Contact{"paul@example.com", "Paul", Contact::Type::Cc},
|
||||||
Contact{"george@example.com", "George", Field::Id::Cc},
|
Contact{"george@example.com", "George", Contact::Type::Cc},
|
||||||
Contact{"james@example.com", "James", Field::Id::From},
|
Contact{"james@example.com", "James", Contact::Type::From},
|
||||||
Contact{"lars@example.com", "Lars", Field::Id::To},
|
Contact{"lars@example.com", "Lars", Contact::Type::To},
|
||||||
Contact{"kirk@example.com", "Kirk", Field::Id::To},
|
Contact{"kirk@example.com", "Kirk", Contact::Type::To},
|
||||||
Contact{"jason@example.com", "Jason", Field::Id::To}
|
Contact{"jason@example.com", "Jason", Contact::Type::To}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -241,8 +249,8 @@ test_bcc()
|
||||||
doc.add(Field::Id::Bcc, test_contacts);
|
doc.add(Field::Id::Bcc, test_contacts);
|
||||||
|
|
||||||
Contacts expected_contacts = {{
|
Contacts expected_contacts = {{
|
||||||
Contact{"john@example.com", "John", Field::Id::Bcc},
|
Contact{"john@example.com", "John", Contact::Type::Bcc},
|
||||||
Contact{"ringo@example.com", "Ringo", Field::Id::Bcc},
|
Contact{"ringo@example.com", "Ringo", Contact::Type::Bcc},
|
||||||
}};
|
}};
|
||||||
const auto actual_contacts = doc.contacts_value(Field::Id::Bcc);
|
const auto actual_contacts = doc.contacts_value(Field::Id::Bcc);
|
||||||
assert_same_contacts(expected_contacts, actual_contacts);
|
assert_same_contacts(expected_contacts, actual_contacts);
|
||||||
|
@ -251,8 +259,8 @@ test_bcc()
|
||||||
{
|
{
|
||||||
Document doc;
|
Document doc;
|
||||||
Contacts contacts = {{
|
Contacts contacts = {{
|
||||||
Contact{"john@example.com", "John Lennon", Field::Id::Bcc},
|
Contact{"john@example.com", "John Lennon", Contact::Type::Bcc},
|
||||||
Contact{"ringo@example.com", "Ringo", Field::Id::Bcc},
|
Contact{"ringo@example.com", "Ringo", Contact::Type::Bcc},
|
||||||
}};
|
}};
|
||||||
doc.add(Field::Id::Bcc, contacts);
|
doc.add(Field::Id::Bcc, contacts);
|
||||||
|
|
||||||
|
@ -273,8 +281,8 @@ test_cc()
|
||||||
doc.add(Field::Id::Cc, test_contacts);
|
doc.add(Field::Id::Cc, test_contacts);
|
||||||
|
|
||||||
Contacts expected_contacts = {{
|
Contacts expected_contacts = {{
|
||||||
Contact{"paul@example.com", "Paul", Field::Id::Cc},
|
Contact{"paul@example.com", "Paul", Contact::Type::Cc},
|
||||||
Contact{"george@example.com", "George", Field::Id::Cc}
|
Contact{"george@example.com", "George", Contact::Type::Cc}
|
||||||
}};
|
}};
|
||||||
const auto actual_contacts = doc.contacts_value(Field::Id::Cc);
|
const auto actual_contacts = doc.contacts_value(Field::Id::Cc);
|
||||||
|
|
||||||
|
@ -289,7 +297,7 @@ test_from()
|
||||||
doc.add(Field::Id::From, test_contacts);
|
doc.add(Field::Id::From, test_contacts);
|
||||||
|
|
||||||
Contacts expected_contacts = {{
|
Contacts expected_contacts = {{
|
||||||
Contact{"james@example.com", "James", Field::Id::From},
|
Contact{"james@example.com", "James", Contact::Type::From},
|
||||||
}};
|
}};
|
||||||
const auto actual_contacts = doc.contacts_value(Field::Id::From);
|
const auto actual_contacts = doc.contacts_value(Field::Id::From);
|
||||||
|
|
||||||
|
@ -303,9 +311,9 @@ test_to()
|
||||||
doc.add(Field::Id::To, test_contacts);
|
doc.add(Field::Id::To, test_contacts);
|
||||||
|
|
||||||
Contacts expected_contacts = {{
|
Contacts expected_contacts = {{
|
||||||
Contact{"lars@example.com", "Lars", Field::Id::To},
|
Contact{"lars@example.com", "Lars", Contact::Type::To},
|
||||||
Contact{"kirk@example.com", "Kirk", Field::Id::To},
|
Contact{"kirk@example.com", "Kirk", Contact::Type::To},
|
||||||
Contact{"jason@example.com", "Jason", Field::Id::To}
|
Contact{"jason@example.com", "Jason", Contact::Type::To}
|
||||||
}};
|
}};
|
||||||
const auto actual_contacts = doc.contacts_value(Field::Id::To);
|
const auto actual_contacts = doc.contacts_value(Field::Id::To);
|
||||||
|
|
||||||
|
|
|
@ -267,31 +267,64 @@ MimeMessage::date() const noexcept
|
||||||
return g_date_time_to_unix(dt);
|
return g_date_time_to_unix(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mu::Contacts
|
constexpr Option<GMimeAddressType>
|
||||||
MimeMessage::addresses(AddressType atype) const noexcept
|
address_type(Contact::Type ctype)
|
||||||
{
|
{
|
||||||
auto addrs{g_mime_message_get_addresses(
|
switch(ctype) {
|
||||||
self(), static_cast<GMimeAddressType>(atype))};
|
case Contact::Type::Bcc:
|
||||||
|
return GMIME_ADDRESS_TYPE_BCC;
|
||||||
|
case Contact::Type::Cc:
|
||||||
|
return GMIME_ADDRESS_TYPE_CC;
|
||||||
|
case Contact::Type::From:
|
||||||
|
return GMIME_ADDRESS_TYPE_FROM;
|
||||||
|
case Contact::Type::To:
|
||||||
|
return GMIME_ADDRESS_TYPE_TO;
|
||||||
|
case Contact::Type::ReplyTo:
|
||||||
|
return GMIME_ADDRESS_TYPE_REPLY_TO;
|
||||||
|
case Contact::Type::Sender:
|
||||||
|
return GMIME_ADDRESS_TYPE_SENDER;
|
||||||
|
default:
|
||||||
|
return Nothing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Mu::Contacts
|
||||||
|
all_contacts(const MimeMessage& msg)
|
||||||
|
{
|
||||||
|
Contacts contacts;
|
||||||
|
|
||||||
|
for (auto&& cctype: {
|
||||||
|
Contact::Type::Sender,
|
||||||
|
Contact::Type::From,
|
||||||
|
Contact::Type::ReplyTo,
|
||||||
|
Contact::Type::To,
|
||||||
|
Contact::Type::Cc,
|
||||||
|
Contact::Type::Bcc
|
||||||
|
}) {
|
||||||
|
auto addrs{msg.contacts(cctype)};
|
||||||
|
std::move(addrs.begin(), addrs.end(),
|
||||||
|
std::back_inserter(contacts));
|
||||||
|
}
|
||||||
|
|
||||||
|
return contacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mu::Contacts
|
||||||
|
MimeMessage::contacts(Contact::Type ctype) const noexcept
|
||||||
|
{
|
||||||
|
/* special case: get all */
|
||||||
|
if (ctype == Contact::Type::None)
|
||||||
|
return all_contacts(*this);
|
||||||
|
|
||||||
|
const auto atype{address_type(ctype)};
|
||||||
|
if (!atype)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto addrs{g_mime_message_get_addresses(self(), *atype)};
|
||||||
if (!addrs)
|
if (!addrs)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
||||||
const auto msgtime{date().value_or(0)};
|
const auto msgtime{date().value_or(0)};
|
||||||
const auto opt_field_id = std::invoke(
|
|
||||||
[&]()->Option<Field::Id>{
|
|
||||||
switch(atype) {
|
|
||||||
case AddressType::To:
|
|
||||||
return Field::Id::To;
|
|
||||||
case AddressType::From:
|
|
||||||
return Field::Id::From;
|
|
||||||
case AddressType::Bcc:
|
|
||||||
return Field::Id::Bcc;
|
|
||||||
case AddressType::Cc:
|
|
||||||
return Field::Id::Cc;
|
|
||||||
default:
|
|
||||||
return Nothing;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Contacts contacts;
|
Contacts contacts;
|
||||||
auto lst_len{internet_address_list_length(addrs)};
|
auto lst_len{internet_address_list_length(addrs)};
|
||||||
|
@ -309,8 +342,7 @@ MimeMessage::addresses(AddressType atype) const noexcept
|
||||||
if (G_UNLIKELY(!email))
|
if (G_UNLIKELY(!email))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
contacts.push_back(Contact{email, name ? name : "",
|
contacts.emplace_back(email, name ? name : "", ctype, msgtime);
|
||||||
opt_field_id, msgtime});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return contacts;
|
return contacts;
|
||||||
|
@ -343,12 +375,11 @@ MimeMessage::references() const noexcept
|
||||||
|
|
||||||
for (auto i = 0; i != g_mime_references_length(mime_refs); ++i) {
|
for (auto i = 0; i != g_mime_references_length(mime_refs); ++i) {
|
||||||
|
|
||||||
if (auto&& msgid{g_mime_references_get_message_id(mime_refs, i)}; !msgid)
|
const auto msgid{g_mime_references_get_message_id(mime_refs, i)};
|
||||||
continue; // invalid
|
if (!msgid || is_dup(refs, msgid))
|
||||||
else if (is_dup(refs, msgid))
|
continue; // invalid or skip dups
|
||||||
continue; // skip dups
|
|
||||||
else
|
refs.emplace_back(msgid);
|
||||||
refs.emplace_back(msgid);
|
|
||||||
}
|
}
|
||||||
g_mime_references_free(mime_refs);
|
g_mime_references_free(mime_refs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -914,21 +914,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static Result<MimeMessage> make_from_text (const std::string& text);
|
static Result<MimeMessage> make_from_text (const std::string& text);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address types
|
* Get the contacts of a given type, or None for _all_
|
||||||
*
|
*
|
||||||
|
* @param ctype contact type
|
||||||
|
*
|
||||||
|
* @return contacts
|
||||||
*/
|
*/
|
||||||
enum struct AddressType {
|
Contacts contacts(Contact::Type ctype) const noexcept;
|
||||||
Sender = GMIME_ADDRESS_TYPE_SENDER,
|
|
||||||
From = GMIME_ADDRESS_TYPE_FROM,
|
|
||||||
ReplyTo = GMIME_ADDRESS_TYPE_REPLY_TO,
|
|
||||||
To = GMIME_ADDRESS_TYPE_TO,
|
|
||||||
Cc = GMIME_ADDRESS_TYPE_CC,
|
|
||||||
Bcc = GMIME_ADDRESS_TYPE_BCC
|
|
||||||
};
|
|
||||||
|
|
||||||
Contacts addresses(AddressType atype) const noexcept;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the message-id if it exists, or nullopt otherwise.
|
* Gets the message-id if it exists, or nullopt otherwise.
|
||||||
|
|
Loading…
Reference in New Issue