* mu-contacts: allow saving a separate value 'personal'

which, if true, means that the contact was seen in a message where at least
  one of the addresses in the recipients field was 'my' address (this is
  decided when in mu-store-write.cc). using this, we can exclude mailing list
  posts.
This commit is contained in:
djcb
2012-06-18 17:59:27 +03:00
parent b7744e0da2
commit be46769255
2 changed files with 66 additions and 36 deletions

View File

@ -30,16 +30,21 @@
#define EMAIL_KEY "email" #define EMAIL_KEY "email"
#define NAME_KEY "name" #define NAME_KEY "name"
#define TSTAMP_KEY "tstamp" #define TSTAMP_KEY "tstamp"
#define PERSONAL_KEY "personal"
/* note: 'personal' here means a mail where my e-mail addresses is explicitly
* in one of the address fields, ie., it's not some mailing list message */
struct _ContactInfo { struct _ContactInfo {
gchar *_name, *_email; gchar * _name, *_email;
time_t _tstamp; gboolean _personal;
time_t _tstamp;
}; };
typedef struct _ContactInfo ContactInfo; typedef struct _ContactInfo ContactInfo;
static void contact_info_destroy (ContactInfo *cinfo); static void contact_info_destroy (ContactInfo *cinfo);
static ContactInfo *contact_info_new (char *email, char *name, static ContactInfo *contact_info_new (char *email, char *name,
time_t tstamp); gboolean personal, time_t tstamp);
struct _MuContacts { struct _MuContacts {
GKeyFile *_ccache; GKeyFile *_ccache;
@ -109,33 +114,32 @@ load_key_file (const char *path)
static gboolean static gboolean
get_values (GKeyFile *kfile, const gchar *group, get_values (GKeyFile *kfile, const gchar *group,
gchar **email, gchar **name, size_t *tstamp) gchar **email, gchar **name, gboolean *personal, size_t *tstamp)
{ {
GError *err; GError *err;
err = NULL; err = NULL;
*email = g_key_file_get_value (kfile, group, EMAIL_KEY, &err);
if (!*email) { do {
g_warning ("cannot get e-mail for %s: %s", *email = g_key_file_get_value (kfile, group, EMAIL_KEY, &err);
group, err->message ? err->message: "error"); if (!*email)
break;
*tstamp = (time_t)g_key_file_get_integer (kfile, group, TSTAMP_KEY, &err);
if (err) if (err)
g_error_free (err); break;
return FALSE;
}
*tstamp = (time_t)g_key_file_get_integer (kfile, group, TSTAMP_KEY, &err); *personal = g_key_file_get_boolean (kfile, group, PERSONAL_KEY, NULL);
if (err) { *name = g_key_file_get_value (kfile, group, NAME_KEY, NULL);
g_warning ("cannot get timestamp for %s: %s",
group, err->message ? err->message: "error");
if (err)
g_error_free (err);
return FALSE;
}
/* name is not required */ return TRUE;
*name = g_key_file_get_value (kfile, group, NAME_KEY, NULL);
return TRUE; } while (0);
g_warning ("error getting value for %s: %s",
group, err->message ? err->message: "error");
g_clear_error (&err);
return FALSE;
} }
@ -150,11 +154,12 @@ deserialize_cache (MuContacts *self)
ContactInfo *cinfo; ContactInfo *cinfo;
char *name, *email; char *name, *email;
size_t tstamp; size_t tstamp;
gboolean personal;
if (!get_values (self->_ccache, groups[i], if (!get_values (self->_ccache, groups[i],
&email, &name, &tstamp)) &email, &name, &personal, &tstamp))
continue; /* ignore this one... */ continue; /* ignore this one... */
cinfo = contact_info_new (email, name, tstamp); cinfo = contact_info_new (email, name, personal, tstamp);
/* note, we're using the groups[i], so don't free with g_strfreev */ /* note, we're using the groups[i], so don't free with g_strfreev */
g_hash_table_insert (self->_hash, groups[i], g_hash_table_insert (self->_hash, groups[i],
@ -228,8 +233,8 @@ mu_contacts_clear (MuContacts *self)
gboolean gboolean
mu_contacts_add (MuContacts *self, const char *email, const char* name, mu_contacts_add (MuContacts *self, const char *email, const char *name,
time_t tstamp) gboolean personal, time_t tstamp)
{ {
ContactInfo *cinfo; ContactInfo *cinfo;
const char* group; const char* group;
@ -246,7 +251,7 @@ mu_contacts_add (MuContacts *self, const char *email, const char* name,
if (!cinfo || (cinfo->_tstamp < tstamp && !mu_str_is_empty(name))) { if (!cinfo || (cinfo->_tstamp < tstamp && !mu_str_is_empty(name))) {
ContactInfo *ci; ContactInfo *ci;
ci = contact_info_new (g_strdup(email), ci = contact_info_new (g_strdup(email),
name ? g_strdup(name) : NULL, name ? g_strdup(name) : NULL, personal,
tstamp); tstamp);
g_hash_table_insert (self->_hash, g_strdup(group), ci); g_hash_table_insert (self->_hash, g_strdup(group), ci);
@ -283,8 +288,9 @@ each_contact (const char *group, ContactInfo *ci, EachContactData *ecdata)
return; /* nothing matched, ignore this one */ return; /* nothing matched, ignore this one */
} }
ecdata->_func (ci->_email, ci->_name, ecdata->_func (ci->_email, ci->_name, ci->_personal,
ci->_tstamp, ecdata->_user_data); ci->_tstamp, ecdata->_user_data);
++ecdata->_num; ++ecdata->_num;
} }
@ -340,6 +346,8 @@ each_keyval (const char *group, ContactInfo *cinfo, MuContacts *self)
g_key_file_set_value (self->_ccache, group, EMAIL_KEY, g_key_file_set_value (self->_ccache, group, EMAIL_KEY,
cinfo->_email); cinfo->_email);
g_key_file_set_boolean (self->_ccache, group, PERSONAL_KEY,
cinfo->_personal);
g_key_file_set_integer (self->_ccache, group, TSTAMP_KEY, g_key_file_set_integer (self->_ccache, group, TSTAMP_KEY,
(int)cinfo->_tstamp); (int)cinfo->_tstamp);
} }
@ -351,7 +359,7 @@ serialize_cache (MuContacts *self)
gsize len; gsize len;
gboolean rv; gboolean rv;
g_hash_table_foreach (self->_hash, (GHFunc) each_keyval, self); g_hash_table_foreach (self->_hash, (GHFunc)each_keyval, self);
/* Note: err arg is unused */ /* Note: err arg is unused */
data = g_key_file_to_data (self->_ccache, &len, NULL); data = g_key_file_to_data (self->_ccache, &len, NULL);
@ -412,7 +420,7 @@ clear_str (char* str)
/* note, we will *own* the name, email we get, and we'll free them in /* note, we will *own* the name, email we get, and we'll free them in
* the end... */ * the end... */
static ContactInfo * static ContactInfo *
contact_info_new (char *email, char *name, time_t tstamp) contact_info_new (char *email, char *name, gboolean personal, time_t tstamp)
{ {
ContactInfo *cinfo; ContactInfo *cinfo;
@ -426,9 +434,10 @@ contact_info_new (char *email, char *name, time_t tstamp)
clear_str (email); clear_str (email);
clear_str (name); clear_str (name);
cinfo->_email = email; cinfo->_email = email;
cinfo->_name = name; cinfo->_name = name;
cinfo->_tstamp = tstamp; cinfo->_personal = personal;
cinfo->_tstamp = tstamp;
return cinfo; return cinfo;
} }
@ -445,3 +454,11 @@ contact_info_destroy (ContactInfo *cinfo)
g_slice_free (ContactInfo, cinfo); g_slice_free (ContactInfo, cinfo);
} }
size_t
mu_contacts_count (MuContacts *self)
{
g_return_val_if_fail (self, 0);
return g_hash_table_size (self->_hash);
}

View File

@ -49,12 +49,14 @@ MuContacts* mu_contacts_new (const gchar *ccachefile)
* @param contacts a contacts object * @param contacts a contacts object
* @param email e-mail address of the contact (not NULL) * @param email e-mail address of the contact (not NULL)
* @param name name of the contact (or NULL) * @param name name of the contact (or NULL)
* @param personal whether the contact is 'personal' (ie., my address
* appears in one of the address fields)
* @param tstamp timestamp for this address * @param tstamp timestamp for this address
* *
* @return TRUE if succeeded, FALSE otherwise * @return TRUE if succeeded, FALSE otherwise
*/ */
gboolean mu_contacts_add (MuContacts *self, const char *email, gboolean mu_contacts_add (MuContacts *self, const char *email,
const char* name, time_t tstamp); const char* name, gboolean personal, time_t tstamp);
/** /**
* destroy the Contacts object * destroy the Contacts object
@ -83,13 +85,24 @@ void mu_contacts_clear (MuContacts *self);
const gchar* mu_contacts_get_path (MuContacts *self); const gchar* mu_contacts_get_path (MuContacts *self);
/**
* return the number of contacts
*
* @param self a contacts object
*
* @return the number of contacts
*/
size_t mu_contacts_count (MuContacts *self);
/** /**
* call called for mu_contacts_foreach; returns the e-mail address, * call called for mu_contacts_foreach; returns the e-mail address,
* name (which may be NULL) and the timestamp for the address * name (which may be NULL) , whether the message is 'personal', and
* the timestamp for the address
* *
*/ */
typedef void (*MuContactsForeachFunc) (const char *email, const char *name, typedef void (*MuContactsForeachFunc) (const char *email, const char *name,
gboolean personal,
time_t tstamp, gpointer user_data); time_t tstamp, gpointer user_data);
/** /**