* WIP: mu-contacts; add the following: return timestamp callback and add regexp filtering capabilities

This commit is contained in:
Dirk-Jan C. Binnema 2011-03-03 21:22:11 +02:00
parent b9be7f210c
commit 6226754a25
5 changed files with 79 additions and 18 deletions

View File

@ -132,11 +132,14 @@ mu_cmd_mkdir (MuConfig *opts)
static void
each_contact (const char *email, const char *name, gpointer data)
each_contact (const char *email, const char *name, time_t tstamp, gpointer data)
{
g_print ("%s %s\n", email, name ? name : "");
g_print ("%u: %s %s\n", (unsigned)tstamp, email, name ? name : "");
}
MuExitCode
mu_cmd_cfind (MuConfig *opts)
{
@ -157,7 +160,8 @@ mu_cmd_cfind (MuConfig *opts)
return MU_EXITCODE_ERROR;
}
mu_contacts_foreach (contacts, (MuContactsForeachFunc)each_contact, NULL);
mu_contacts_foreach (contacts, (MuContactsForeachFunc)each_contact, NULL,
opts->params[1]);
mu_contacts_destroy (contacts);
return MU_OK;

View File

@ -22,6 +22,7 @@
#include "mu-contacts.h"
#include "mu-util.h"
#include "mu-str.h"
#define MU_CONTACTS_NAME_KEY "name"
#define MU_CONTACTS_TIMESTAMP_KEY "timestamp"
@ -123,7 +124,7 @@ mu_contacts_add (MuContacts *self, const char* name, const char *email,
* empty name */
cinfo = (ContactInfo*) g_hash_table_lookup (self->_hash, email);
if (!cinfo ||
(cinfo->_tstamp < tstamp && name && name[0] != '\0')) {
(cinfo->_tstamp < tstamp && !mu_str_is_empty(name))) {
g_hash_table_insert (self->_hash, g_strdup(email),
contact_info_new (name, tstamp));
return self->_dirty = TRUE;
@ -135,30 +136,65 @@ mu_contacts_add (MuContacts *self, const char* name, const char *email,
struct _EachContactData {
MuContactsForeachFunc _func;
gpointer _user_data;
GRegex *_rx;
};
typedef struct _EachContactData EachContactData;
static void
static void /* email will never be NULL, but ci->_name may be */
each_contact (const char* email, ContactInfo *ci, EachContactData *ecdata)
{
ecdata->_func (email, ci->_name, ecdata->_user_data);
/* ignore this contact if we have a regexp, and it matches
* neither email nor name (if we have a name) */
while (ecdata->_rx) { /* note, only once */
if (g_regex_match (ecdata->_rx, email, 0, NULL))
break; /* email matches? continue! */
if (!ci->_name)
return; /* email did not match, no name? ignore this one */
if (g_regex_match (ecdata->_rx,ci->_name, 0, NULL))
break; /* name matches? continue! */
return; /* nothing matched, ignore this one */
}
ecdata->_func (email, ci->_name, ci->_tstamp, ecdata->_user_data);
}
void
gboolean
mu_contacts_foreach (MuContacts *self, MuContactsForeachFunc func,
gpointer user_data)
gpointer user_data, const char *pattern)
{
EachContactData ecdata;
g_return_if_fail (self);
g_return_if_fail (func);
g_return_val_if_fail (self, FALSE);
g_return_val_if_fail (func, FALSE);
if (pattern) {
GError *err;
err = NULL;
ecdata._rx = g_regex_new
(pattern, G_REGEX_CASELESS|G_REGEX_EXTENDED|G_REGEX_OPTIMIZE,
0, &err);
if (!ecdata._rx) {
g_warning ("error in regexp '%s': %s", pattern, err->message);
g_error_free (err);
return FALSE;
}
} else
ecdata._rx = NULL;
ecdata._func = func;
ecdata._user_data = user_data;
g_hash_table_foreach (self->_hash, (GHFunc) each_contact, &ecdata);
}
if (ecdata._rx)
g_regex_unref (ecdata._rx);
return TRUE;
}
static void
each_keyval (const char *email, ContactInfo *cinfo, MuContacts *self)

View File

@ -62,19 +62,29 @@ gboolean mu_contacts_add (MuContacts *contacts, const char* name, const char *em
*/
void mu_contacts_destroy (MuContacts *contacts);
typedef void (*MuContactsForeachFunc) (const char *email, const char *name,
/**
* call called for mu_contacts_foreach; returns the e-mail address,
* name (which may be NULL) and the timestamp for the address
*
*/
typedef void (*MuContactsForeachFunc) (const char *email, const char *name, time_t tstamp,
gpointer user_data);
/**
* call a function for each contact
* call a function for either each contact, or each contact satisfying
* a regular expression,
*
* @param contacts contacts object
* @param func callback function to be called for each
* @param user_data user data to pass to the callback
* @param pattern a regular expression which matches either the e-mail
* or name, to filter out contacts, or NULL to not do any filtering.
*
* @return TRUE if the function succeeded, or FALSE if the provide
* regular expression was invalid (and not NULL)
*/
void mu_contacts_foreach (MuContacts *contacts, MuContactsForeachFunc func,
gpointer user_data);
gboolean mu_contacts_foreach (MuContacts *contacts, MuContactsForeachFunc func,
gpointer user_data, const char* pattern);
G_END_DECLS

View File

@ -496,7 +496,7 @@ each_contact_info (MuMsgContact *contact, MsgDoc *msgdoc)
msgdoc->_doc->add_term
(std::string (*pfxp + escaped, 0, MU_STORE_MAX_TERM_LENGTH));
g_free (escaped);
/* store it also in our contacts cache */
if (msgdoc->_store->_contacts)
mu_contacts_add (msgdoc->_store->_contacts,

View File

@ -223,7 +223,7 @@ time_t mu_str_date_parse_hdwmy (const char* str);
*
* @param str a string with a size, such a "100", "100Kb", "1Mb"
*
* @return
* @return the corresponding time_t value (as a guint64)
*/
guint64 mu_str_size_parse_kmg (const char* str);
@ -250,6 +250,17 @@ const char* mu_str_fullpath_s (const char* path, const char* name);
char* mu_str_escape_c_literal (const gchar* str)
G_GNUC_WARN_UNUSED_RESULT;
/**
* macro to check whether the string is empty, ie. if it's NULL or
* it's length is 0
*
* @param S a string
*
* @return TRUE if the string is empty, FALSE otherwise
*/
#define mu_str_is_empty(S) ((!(S)||!(S)[0])?TRUE:FALSE)
G_END_DECLS
#endif /*__MU_STR_H__*/