mirror of https://github.com/djcb/mu.git
parent
d436a47c1f
commit
3aa053e158
|
@ -77,9 +77,10 @@ struct MessageContact {
|
||||||
*
|
*
|
||||||
* @param email_ email address
|
* @param email_ email address
|
||||||
* @param name_ name or empty
|
* @param name_ name or empty
|
||||||
|
* @param message_date_ date of message this contact originate from
|
||||||
* @param personal_ is this a personal contact?
|
* @param personal_ is this a personal contact?
|
||||||
* @param last_seen_ when was this contact last seen?
|
|
||||||
* @param freq_ how often was this contact seen?
|
* @param freq_ how often was this contact seen?
|
||||||
|
* @param tstamp_ timestamp for last change
|
||||||
*/
|
*/
|
||||||
MessageContact(const std::string& email_, const std::string& name_,
|
MessageContact(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_,
|
||||||
|
|
|
@ -48,21 +48,17 @@ add_prop_nonempty(Sexp::List& list, const char* name, const char* str)
|
||||||
list.add_prop(name, Sexp::make_string(str));
|
list.add_prop(name, Sexp::make_string(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Sexp
|
|
||||||
make_contact_sexp(MuMsgContact* c)
|
static Mu::Sexp
|
||||||
|
make_contact_sexp(const MessageContact& contact)
|
||||||
{
|
{
|
||||||
// a cons-pair...perhaps make this a plist too?
|
return Sexp::make_list(
|
||||||
|
/* name */
|
||||||
Sexp::List contact;
|
Sexp::make_string(contact.name, true/*?nil*/),
|
||||||
if (mu_msg_contact_name(c))
|
/* dot */
|
||||||
contact.add(Sexp::make_string(Mu::remove_ctrl(mu_msg_contact_name(c))));
|
Sexp::make_symbol("."),
|
||||||
else
|
/* email */
|
||||||
contact.add(Sexp::make_symbol("nil"));
|
Sexp::make_string(contact.email));
|
||||||
|
|
||||||
contact.add(Sexp::make_symbol("."));
|
|
||||||
contact.add(Sexp::make_string(Mu::remove_ctrl(mu_msg_contact_email(c))));
|
|
||||||
|
|
||||||
return Sexp::make_list(std::move(contact));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -86,9 +82,8 @@ add_list_post(Sexp::List& list, MuMsg* msg)
|
||||||
g_return_if_fail(rx);
|
g_return_if_fail(rx);
|
||||||
|
|
||||||
if (g_regex_match(rx, list_post, (GRegexMatchFlags)0, &minfo)) {
|
if (g_regex_match(rx, list_post, (GRegexMatchFlags)0, &minfo)) {
|
||||||
auto address = (char*)g_match_info_fetch(minfo, 1);
|
auto address = (char*)g_match_info_fetch(minfo, 1);
|
||||||
MuMsgContact contact{NULL, address, {}, {}};
|
list.add_prop(":list-post", make_contact_sexp(MessageContact{address}));
|
||||||
list.add_prop(":list-post", Sexp::make_list(make_contact_sexp(&contact)));
|
|
||||||
g_free(address);
|
g_free(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,47 +91,31 @@ add_list_post(Sexp::List& list, MuMsg* msg)
|
||||||
g_regex_unref(rx);
|
g_regex_unref(rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _ContactData {
|
|
||||||
Sexp::List from, to, cc, bcc, reply_to;
|
|
||||||
};
|
|
||||||
typedef struct _ContactData ContactData;
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
each_contact(MuMsgContact* c, ContactData* cdata)
|
|
||||||
{
|
|
||||||
switch (mu_msg_contact_type(c)) {
|
|
||||||
case MU_MSG_CONTACT_TYPE_FROM: cdata->from.add(make_contact_sexp(c)); break;
|
|
||||||
case MU_MSG_CONTACT_TYPE_TO: cdata->to.add(make_contact_sexp(c)); break;
|
|
||||||
case MU_MSG_CONTACT_TYPE_CC: cdata->cc.add(make_contact_sexp(c)); break;
|
|
||||||
case MU_MSG_CONTACT_TYPE_BCC: cdata->bcc.add(make_contact_sexp(c)); break;
|
|
||||||
case MU_MSG_CONTACT_TYPE_REPLY_TO: cdata->reply_to.add(make_contact_sexp(c)); break;
|
|
||||||
default: g_return_val_if_reached(FALSE); return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_prop_nonempty_list(Sexp::List& list, std::string&& name, Sexp::List&& sexp)
|
|
||||||
{
|
|
||||||
if (sexp.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
list.add_prop(std::move(name), Sexp::make_list(std::move(sexp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_contacts(Sexp::List& list, MuMsg* msg)
|
add_contacts(Sexp::List& list, MuMsg* msg)
|
||||||
{
|
{
|
||||||
ContactData cdata{};
|
using ContactPair = std::pair<MessageContact::Type, std::string_view>;
|
||||||
mu_msg_contact_foreach(msg, (MuMsgContactForeachFunc)each_contact, &cdata);
|
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" },
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (auto&& contact_type : contact_types) {
|
||||||
|
|
||||||
|
const auto contacts{mu_msg_get_contacts(msg, contact_type.first)};
|
||||||
|
if (contacts.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
add_prop_nonempty_list(list, ":from", std::move(cdata.from));
|
Sexp::List c_list;
|
||||||
add_prop_nonempty_list(list, ":to", std::move(cdata.to));
|
for (auto&& contact: contacts)
|
||||||
add_prop_nonempty_list(list, ":cc", std::move(cdata.cc));
|
c_list.add(make_contact_sexp(contact));
|
||||||
add_prop_nonempty_list(list, ":bcc", std::move(cdata.bcc));
|
|
||||||
add_prop_nonempty_list(list, ":reply-to", std::move(cdata.reply_to));
|
|
||||||
|
|
||||||
add_list_post(list, msg);
|
list.add_prop(std::string{contact_type.second},
|
||||||
|
Sexp::make_list(std::move(c_list)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -383,8 +362,10 @@ Mu::msg_to_sexp_list(MuMsg* msg, unsigned docid, MuMsgOptions opts)
|
||||||
|
|
||||||
/* in the no-headers-only case (see below) we get a more complete list of contacts, so no
|
/* 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 */
|
* need to get them here if that's the case */
|
||||||
if (opts & MU_MSG_OPTION_HEADERS_ONLY)
|
if (opts & MU_MSG_OPTION_HEADERS_ONLY) {
|
||||||
add_contacts(items, msg);
|
add_contacts(items, msg);
|
||||||
|
add_list_post(items, msg);
|
||||||
|
}
|
||||||
|
|
||||||
add_prop_nonempty(items, ":references", mu_msg_get_references(msg));
|
add_prop_nonempty(items, ":references", mu_msg_get_references(msg));
|
||||||
add_prop_nonempty(items, ":in-reply-to", mu_msg_get_header(msg, "In-Reply-To"));
|
add_prop_nonempty(items, ":in-reply-to", mu_msg_get_header(msg, "In-Reply-To"));
|
||||||
|
|
167
lib/mu-msg.cc
167
lib/mu-msg.cc
|
@ -17,6 +17,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -26,7 +27,12 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <gmime/gmime.h>
|
#include <gmime/gmime.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
|
||||||
|
#include "gmime/gmime-message.h"
|
||||||
|
#include "mu-message-contact.hh"
|
||||||
#include "mu-msg-priv.hh" /* include before mu-msg.h */
|
#include "mu-msg-priv.hh" /* include before mu-msg.h */
|
||||||
#include "mu-msg.hh"
|
#include "mu-msg.hh"
|
||||||
#include "utils/mu-str.h"
|
#include "utils/mu-str.h"
|
||||||
|
@ -608,131 +614,66 @@ Mu::mu_msg_get_field_numeric(MuMsg* self, MuMsgFieldId mfid)
|
||||||
return get_num_field(self, mfid);
|
return get_num_field(self, mfid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
fill_contact(MuMsgContact* self, InternetAddress* addr, MuMsgContactType ctype)
|
static Mu::MessageContacts
|
||||||
|
get_all_contacts(MuMsg *self)
|
||||||
{
|
{
|
||||||
if (!addr)
|
MessageContacts contacts;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
self->full_address = internet_address_to_string(addr, NULL, FALSE);
|
for (auto&& mtype : { MessageContact::Type::From, MessageContact::Type::To,
|
||||||
|
MessageContact::Type::Cc, MessageContact::Type::ReplyTo,
|
||||||
self->name = internet_address_get_name(addr);
|
MessageContact::Type::Bcc}) {
|
||||||
if (mu_str_is_empty(self->name)) {
|
auto type_contacts{mu_msg_get_contacts(self, mtype)};
|
||||||
self->name = NULL;
|
|
||||||
|
contacts.reserve(contacts.size() + type_contacts.size());
|
||||||
|
contacts.insert(contacts.end(), type_contacts.begin(), type_contacts.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
self->type = ctype;
|
return contacts;
|
||||||
|
|
||||||
/* we only support internet mailbox addresses; if we don't
|
|
||||||
* check, g_mime hits an assert
|
|
||||||
*/
|
|
||||||
if (INTERNET_ADDRESS_IS_MAILBOX(addr))
|
|
||||||
self->email = internet_address_mailbox_get_addr(INTERNET_ADDRESS_MAILBOX(addr));
|
|
||||||
else
|
|
||||||
self->email = NULL;
|
|
||||||
|
|
||||||
/* if there's no address, just a name, it's probably a local
|
|
||||||
* address (without @) */
|
|
||||||
if (self->name && !self->email)
|
|
||||||
self->email = self->name;
|
|
||||||
|
|
||||||
/* note, the address could be NULL e.g. when the recipient is something
|
|
||||||
* like 'Undisclosed recipients'
|
|
||||||
*/
|
|
||||||
return self->email != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
Mu::MessageContacts
|
||||||
address_list_foreach(InternetAddressList* addrlist,
|
Mu::mu_msg_get_contacts(MuMsg *self, MessageContact::Type mtype)
|
||||||
MuMsgContactType ctype,
|
|
||||||
MuMsgContactForeachFunc func,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
int i, len;
|
typedef const char*(*AddressFunc)(MuMsg*);
|
||||||
|
using AddressInfo = std::pair<GMimeAddressType, AddressFunc>;
|
||||||
|
|
||||||
if (!addrlist)
|
g_return_val_if_fail(self, MessageContacts{});
|
||||||
return;
|
|
||||||
|
|
||||||
len = internet_address_list_length(addrlist);
|
if (mtype == MessageContact::Type::Unknown)
|
||||||
|
return get_all_contacts(self);
|
||||||
|
|
||||||
|
const auto info = std::invoke([&]()->AddressInfo {
|
||||||
|
switch (mtype) {
|
||||||
|
case MessageContact::Type::From:
|
||||||
|
return { GMIME_ADDRESS_TYPE_FROM, mu_msg_get_from };
|
||||||
|
case MessageContact::Type::To:
|
||||||
|
return { GMIME_ADDRESS_TYPE_TO, mu_msg_get_to };
|
||||||
|
case MessageContact::Type::Cc:
|
||||||
|
return { GMIME_ADDRESS_TYPE_CC, mu_msg_get_cc };
|
||||||
|
case MessageContact::Type::ReplyTo:
|
||||||
|
return { GMIME_ADDRESS_TYPE_REPLY_TO, {} };
|
||||||
|
case MessageContact::Type::Bcc:
|
||||||
|
return { GMIME_ADDRESS_TYPE_BCC, mu_msg_get_bcc };
|
||||||
|
default:
|
||||||
|
throw std::logic_error("bug");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (i = 0; i != len; ++i) {
|
const auto mdate{mu_msg_get_date(self)};
|
||||||
MuMsgContact contact;
|
if (self->_file) {
|
||||||
gboolean keep_going;
|
if (auto&& lst{g_mime_message_get_addresses(
|
||||||
|
self->_file->_mime_msg, info.first)}; lst)
|
||||||
if (!fill_contact(&contact, internet_address_list_get_address(addrlist, i), ctype))
|
return make_message_contacts(lst, mtype, mdate);
|
||||||
continue;
|
} else if (info.second) {
|
||||||
|
if (auto&& lst_str{info.second(self)}; lst_str)
|
||||||
keep_going = func(&contact, user_data);
|
return make_message_contacts(lst_str, mtype, mdate);
|
||||||
g_free((char*)contact.full_address);
|
|
||||||
|
|
||||||
if (!keep_going)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
addresses_foreach(const char* addrs,
|
|
||||||
MuMsgContactType ctype,
|
|
||||||
MuMsgContactForeachFunc func,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
InternetAddressList* addrlist;
|
|
||||||
|
|
||||||
if (!addrs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
addrlist = internet_address_list_parse(NULL, addrs);
|
|
||||||
if (addrlist) {
|
|
||||||
address_list_foreach(addrlist, ctype, func, user_data);
|
|
||||||
g_object_unref(addrlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
msg_contact_foreach_file(MuMsg* msg, MuMsgContactForeachFunc func, gpointer user_data)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct {
|
|
||||||
GMimeAddressType _gmime_type;
|
|
||||||
MuMsgContactType _type;
|
|
||||||
} ctypes[] = {
|
|
||||||
{GMIME_ADDRESS_TYPE_FROM, MU_MSG_CONTACT_TYPE_FROM},
|
|
||||||
{GMIME_ADDRESS_TYPE_REPLY_TO, MU_MSG_CONTACT_TYPE_REPLY_TO},
|
|
||||||
{GMIME_ADDRESS_TYPE_TO, MU_MSG_CONTACT_TYPE_TO},
|
|
||||||
{GMIME_ADDRESS_TYPE_CC, MU_MSG_CONTACT_TYPE_CC},
|
|
||||||
{GMIME_ADDRESS_TYPE_BCC, MU_MSG_CONTACT_TYPE_BCC},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i != G_N_ELEMENTS(ctypes); ++i) {
|
|
||||||
InternetAddressList* addrlist;
|
|
||||||
addrlist =
|
|
||||||
g_mime_message_get_addresses(msg->_file->_mime_msg, ctypes[i]._gmime_type);
|
|
||||||
address_list_foreach(addrlist, ctypes[i]._type, func, user_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
msg_contact_foreach_doc(MuMsg* msg, MuMsgContactForeachFunc func, gpointer user_data)
|
|
||||||
{
|
|
||||||
addresses_foreach(mu_msg_get_from(msg), MU_MSG_CONTACT_TYPE_FROM, func, user_data);
|
|
||||||
addresses_foreach(mu_msg_get_to(msg), MU_MSG_CONTACT_TYPE_TO, func, user_data);
|
|
||||||
addresses_foreach(mu_msg_get_cc(msg), MU_MSG_CONTACT_TYPE_CC, func, user_data);
|
|
||||||
addresses_foreach(mu_msg_get_bcc(msg), MU_MSG_CONTACT_TYPE_BCC, func, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Mu::mu_msg_contact_foreach(MuMsg* msg, MuMsgContactForeachFunc func, gpointer user_data)
|
|
||||||
{
|
|
||||||
g_return_if_fail(msg);
|
|
||||||
g_return_if_fail(func);
|
|
||||||
|
|
||||||
if (msg->_file)
|
|
||||||
msg_contact_foreach_file(msg, func, user_data);
|
|
||||||
else if (msg->_doc)
|
|
||||||
msg_contact_foreach_doc(msg, func, user_data);
|
|
||||||
else
|
|
||||||
g_return_if_reached();
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
Mu::mu_msg_is_readable(MuMsg* self)
|
Mu::mu_msg_is_readable(MuMsg* self)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <mu-message-flags.hh>
|
#include <mu-message-flags.hh>
|
||||||
#include <mu-message-priority.hh>
|
#include <mu-message-priority.hh>
|
||||||
|
#include <mu-message-contact.hh>
|
||||||
|
|
||||||
#include <mu-msg-fields.h>
|
#include <mu-msg-fields.h>
|
||||||
#include <utils/mu-util.h>
|
#include <utils/mu-util.h>
|
||||||
|
@ -439,80 +440,17 @@ bool mu_msg_move_to_maildir(MuMsg* msg,
|
||||||
bool ignore_dups,
|
bool ignore_dups,
|
||||||
bool new_name,
|
bool new_name,
|
||||||
GError** err);
|
GError** err);
|
||||||
|
/**
|
||||||
enum _MuMsgContactType { /* Reply-To:? */
|
* Get a sequence with contacts of the given type for this message.
|
||||||
MU_MSG_CONTACT_TYPE_TO = 0,
|
|
||||||
MU_MSG_CONTACT_TYPE_FROM,
|
|
||||||
MU_MSG_CONTACT_TYPE_CC,
|
|
||||||
MU_MSG_CONTACT_TYPE_BCC,
|
|
||||||
MU_MSG_CONTACT_TYPE_REPLY_TO,
|
|
||||||
|
|
||||||
MU_MSG_CONTACT_TYPE_NUM
|
|
||||||
};
|
|
||||||
typedef guint MuMsgContactType;
|
|
||||||
|
|
||||||
/* not a 'real' contact type */
|
|
||||||
#define MU_MSG_CONTACT_TYPE_ALL (MU_MSG_CONTACT_TYPE_NUM + 1)
|
|
||||||
|
|
||||||
#define mu_msg_contact_type_is_valid(MCT) ((MCT) < MU_MSG_CONTACT_TYPE_NUM)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char* name; /**< Foo Bar */
|
|
||||||
const char* email; /**< foo@bar.cuux */
|
|
||||||
const char* full_address; /**< Foo Bar <foo@bar.cuux> */
|
|
||||||
MuMsgContactType type; /**< MU_MSG_CONTACT_TYPE_{ TO,
|
|
||||||
CC, BCC, FROM, REPLY_TO} */
|
|
||||||
} MuMsgContact;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* macro to get the name of a contact
|
|
||||||
*
|
*
|
||||||
* @param ct a MuMsgContact
|
* @param msg a valid MuMsg* instance
|
||||||
*
|
* @param mtype the contact type; with Type::Unknown, get _all_ types.
|
||||||
* @return the name
|
*
|
||||||
|
* @return a sequence
|
||||||
*/
|
*/
|
||||||
#define mu_msg_contact_name(ct) ((ct)->name)
|
Mu::MessageContacts mu_msg_get_contacts (MuMsg *self,
|
||||||
|
MessageContact::Type mtype=MessageContact::Type::Unknown);
|
||||||
/**
|
|
||||||
* macro to get the email address of a contact
|
|
||||||
*
|
|
||||||
* @param ct a MuMsgContact
|
|
||||||
*
|
|
||||||
* @return the address
|
|
||||||
*/
|
|
||||||
#define mu_msg_contact_email(ct) ((ct)->email)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* macro to get the contact type
|
|
||||||
*
|
|
||||||
* @param ct a MuMsgContact
|
|
||||||
*
|
|
||||||
* @return the contact type
|
|
||||||
*/
|
|
||||||
#define mu_msg_contact_type(ct) ((ct)->type)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* callback function
|
|
||||||
*
|
|
||||||
* @param contact
|
|
||||||
* @param user_data a user provided data pointer
|
|
||||||
*
|
|
||||||
* @return TRUE if we should continue the foreach, FALSE otherwise
|
|
||||||
*/
|
|
||||||
typedef gboolean (*MuMsgContactForeachFunc)(MuMsgContact* contact, gpointer user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* call a function for each of the contacts in a message; the order is:
|
|
||||||
* from to cc bcc (of each there are zero or more)
|
|
||||||
*
|
|
||||||
* @param msg a valid MuMsgGMime* instance
|
|
||||||
* @param func a callback function to call for each contact; when
|
|
||||||
* the callback does not return TRUE, it won't be called again
|
|
||||||
* @param user_data a user-provide pointer that will be passed to the callback
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void mu_msg_contact_foreach(MuMsg* msg, MuMsgContactForeachFunc func, gpointer user_data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a 'display contact' from an email header To/Cc/Bcc/From-type address
|
* create a 'display contact' from an email header To/Cc/Bcc/From-type address
|
||||||
* ie., turn
|
* ie., turn
|
||||||
|
@ -534,6 +472,8 @@ void mu_msg_contact_foreach(MuMsg* msg, MuMsgContactForeachFunc func, gpointer u
|
||||||
const char* mu_str_display_contact_s(const char* str) G_GNUC_CONST;
|
const char* mu_str_display_contact_s(const char* str) G_GNUC_CONST;
|
||||||
char* mu_str_display_contact(const char* str) G_GNUC_WARN_UNUSED_RESULT;
|
char* mu_str_display_contact(const char* str) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct QueryMatch;
|
struct QueryMatch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "test-mu-common.hh"
|
#include "test-mu-common.hh"
|
||||||
#include "mu-msg.hh"
|
#include "mu-msg.hh"
|
||||||
#include "utils/mu-str.h"
|
#include "utils/mu-str.h"
|
||||||
|
#include "utils/mu-utils.hh"
|
||||||
|
|
||||||
using namespace Mu;
|
using namespace Mu;
|
||||||
|
|
||||||
|
@ -57,30 +58,11 @@ get_msg(const char* path)
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_contact_01(MuMsgContact* contact, int* idx)
|
|
||||||
{
|
|
||||||
switch (*idx) {
|
|
||||||
case 0:
|
|
||||||
g_assert_cmpstr(mu_msg_contact_name(contact), ==, "Mickey Mouse");
|
|
||||||
g_assert_cmpstr(mu_msg_contact_email(contact), ==, "anon@example.com");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
g_assert_cmpstr(mu_msg_contact_name(contact), ==, "Donald Duck");
|
|
||||||
g_assert_cmpstr(mu_msg_contact_email(contact), ==, "gcc-help@gcc.gnu.org");
|
|
||||||
break;
|
|
||||||
default: g_assert_not_reached();
|
|
||||||
}
|
|
||||||
++(*idx);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_mu_msg_01(void)
|
test_mu_msg_01(void)
|
||||||
{
|
{
|
||||||
MuMsg* msg;
|
MuMsg* msg;
|
||||||
gint i;
|
|
||||||
|
|
||||||
msg = get_msg(MU_TESTMAILDIR4 "/1220863042.12663_1.mindcrime!2,S");
|
msg = get_msg(MU_TESTMAILDIR4 "/1220863042.12663_1.mindcrime!2,S");
|
||||||
|
|
||||||
|
@ -96,38 +78,21 @@ test_mu_msg_01(void)
|
||||||
"contact gcc-help-help@gcc.gnu.org; run by ezmlm");
|
"contact gcc-help-help@gcc.gnu.org; run by ezmlm");
|
||||||
g_assert_true(mu_msg_get_prio(msg) == Mu::MessagePriority::Normal);
|
g_assert_true(mu_msg_get_prio(msg) == Mu::MessagePriority::Normal);
|
||||||
g_assert_cmpuint(mu_msg_get_date(msg), ==, 1217530645);
|
g_assert_cmpuint(mu_msg_get_date(msg), ==, 1217530645);
|
||||||
|
|
||||||
i = 0;
|
const auto contacts{mu_msg_get_contacts(msg)};
|
||||||
mu_msg_contact_foreach(msg, (MuMsgContactForeachFunc)check_contact_01, &i);
|
g_assert_cmpuint(contacts.size(), == , 2);
|
||||||
g_assert_cmpint(i, ==, 2);
|
g_assert_true(contacts[0].name == "Mickey Mouse");
|
||||||
|
g_assert_true(contacts[0].email == "anon@example.com");
|
||||||
|
g_assert_true(contacts[1].name == "Donald Duck");
|
||||||
|
g_assert_true(contacts[1].email == "gcc-help@gcc.gnu.org");
|
||||||
|
|
||||||
mu_msg_unref(msg);
|
mu_msg_unref(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_contact_02(MuMsgContact* contact, int* idx)
|
|
||||||
{
|
|
||||||
switch (*idx) {
|
|
||||||
case 0:
|
|
||||||
g_assert_cmpstr(mu_msg_contact_name(contact), ==, NULL);
|
|
||||||
g_assert_cmpstr(mu_msg_contact_email(contact), ==, "anon@example.com");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
g_assert_cmpstr(mu_msg_contact_name(contact), ==, NULL);
|
|
||||||
g_assert_cmpstr(mu_msg_contact_email(contact), ==, "help-gnu-emacs@gnu.org");
|
|
||||||
break;
|
|
||||||
default: g_assert_not_reached();
|
|
||||||
}
|
|
||||||
++(*idx);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_mu_msg_02(void)
|
test_mu_msg_02(void)
|
||||||
{
|
{
|
||||||
MuMsg* msg;
|
MuMsg* msg;
|
||||||
int i;
|
|
||||||
|
|
||||||
msg = get_msg(MU_TESTMAILDIR4 "/1220863087.12663_19.mindcrime!2,S");
|
msg = get_msg(MU_TESTMAILDIR4 "/1220863087.12663_19.mindcrime!2,S");
|
||||||
|
|
||||||
|
@ -142,9 +107,13 @@ test_mu_msg_02(void)
|
||||||
== Mu::MessagePriority::Low);
|
== Mu::MessagePriority::Low);
|
||||||
g_assert_cmpuint(mu_msg_get_date(msg), ==, 1218051515);
|
g_assert_cmpuint(mu_msg_get_date(msg), ==, 1218051515);
|
||||||
|
|
||||||
i = 0;
|
const auto contacts{mu_msg_get_contacts(msg)};
|
||||||
mu_msg_contact_foreach(msg, (MuMsgContactForeachFunc)check_contact_02, &i);
|
g_assert_cmpuint(contacts.size(), == , 2);
|
||||||
g_assert_cmpint(i, ==, 2);
|
g_assert_true(contacts[0].name.empty());
|
||||||
|
g_assert_true(contacts[0].email == "anon@example.com");
|
||||||
|
g_assert_true(contacts[1].name.empty());
|
||||||
|
g_assert_true(contacts[1].email == "help-gnu-emacs@gnu.org");
|
||||||
|
|
||||||
g_print("flags: %s\n", Mu::message_flags_to_string(mu_msg_get_flags(msg)).c_str());
|
g_print("flags: %s\n", Mu::message_flags_to_string(mu_msg_get_flags(msg)).c_str());
|
||||||
g_assert_true(mu_msg_get_flags(msg) == (MessageFlags::Seen|MessageFlags::MailingList));
|
g_assert_true(mu_msg_get_flags(msg) == (MessageFlags::Seen|MessageFlags::MailingList));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue