From 3159d97105a9308e5b2146a55d044b10a79f7c4e Mon Sep 17 00:00:00 2001 From: djcb Date: Mon, 18 Jun 2012 18:02:12 +0300 Subject: [PATCH] * mu-store*: detect 'my-addresses' in messages, so we can mark contacts as 'personal' --- lib/mu-store-priv.hh | 30 +++++++++++++++++++++------- lib/mu-store-write.cc | 42 +++++++++++++++++++++++++++++++++++---- lib/mu-store.h | 5 ++++- lib/tests/test-mu-store.c | 8 ++++---- 4 files changed, 69 insertions(+), 16 deletions(-) diff --git a/lib/mu-store-priv.hh b/lib/mu-store-priv.hh index cb7968a9..afe11e84 100644 --- a/lib/mu-store-priv.hh +++ b/lib/mu-store-priv.hh @@ -32,7 +32,7 @@ #include "mu-store.h" #include "mu-contacts.h" - +#include "mu-str.h" class MuStoreError { public: @@ -49,9 +49,11 @@ private: struct _MuStore { public: /* create a read-write MuStore */ - _MuStore (const char *path, const char *contacts_path, bool rebuild) { + _MuStore (const char *path, const char *contacts_path, + const char **my_addresses, + bool rebuild) { - init (path, contacts_path, rebuild, false); + init (path, contacts_path, my_addresses, rebuild, false); if (rebuild) _db = new Xapian::WritableDatabase @@ -64,7 +66,7 @@ public: if (contacts_path) { _contacts = mu_contacts_new (contacts_path); - if (!_contacts) /* don't bail-out for this */ + if (!_contacts) throw MuStoreError (MU_ERROR_FILE, ("failed to init contacts cache")); } @@ -76,7 +78,7 @@ public: /* create a read-only MuStore */ _MuStore (const char *path) { - init (path, NULL, false, false); + init (path, NULL, NULL, false, false); _db = new Xapian::Database (path); if (mu_store_needs_upgrade(this)) @@ -86,7 +88,7 @@ public: MU_WRITE_LOG ("%s: opened %s read-only", __FUNCTION__, this->path()); } - void init (const char *path, const char *contacts_path, + void init (const char *path, const char *contacts_path, const char **my_addresses, bool rebuild, bool read_only) { _batch_size = DEFAULT_BATCH_SIZE; @@ -97,6 +99,15 @@ public: _read_only = read_only; _ref_count = 1; _version = NULL; + + /* copy 'my adresses' */ + _my_addresses = NULL; + while (my_addresses && *my_addresses) { + _my_addresses = g_slist_prepend + (_my_addresses, g_strdup (*my_addresses)); + ++my_addresses; + } + } void check_set_version () { @@ -125,6 +136,8 @@ public: if (!_read_only) mu_store_flush (this); + mu_str_free_list (_my_addresses); + MU_WRITE_LOG ("closing xapian database with %d document(s)", (int)db_read_only()->get_doccount()); delete _db; @@ -201,6 +214,8 @@ public: return --_ref_count; } + GSList *my_addresses () { return _my_addresses; } + /* by default, use transactions of 30000 messages */ static const unsigned DEFAULT_BATCH_SIZE = 30000; /* http://article.gmane.org/gmane.comp.search.xapian.general/3656 */ @@ -220,8 +235,9 @@ private: Xapian::Database *_db; bool _read_only; - guint _ref_count; + + GSList *_my_addresses; }; diff --git a/lib/mu-store-write.cc b/lib/mu-store-write.cc index b8019216..38068d25 100644 --- a/lib/mu-store-write.cc +++ b/lib/mu-store-write.cc @@ -123,14 +123,14 @@ add_synonyms (MuStore *store) MuStore* mu_store_new_writable (const char* xpath, const char *contacts_cache, - gboolean rebuild, GError **err) + const char **my_addresses, gboolean rebuild, GError **err) { g_return_val_if_fail (xpath, NULL); try { try { MuStore *store; - store = new _MuStore (xpath, contacts_cache, + store = new _MuStore (xpath, contacts_cache, my_addresses, rebuild ? true : false); add_synonyms (store); return store; @@ -506,6 +506,10 @@ struct _MsgDoc { MuMsg *_msg; MuStore *_store; GStringChunk *_strchunk; + + /* callback data, to determine whether this message is 'personal' */ + gboolean _personal; + GSList *_my_addresses; }; typedef struct _MsgDoc MsgDoc; @@ -622,21 +626,51 @@ each_contact_info (MuMsgContact *contact, MsgDoc *msgdoc) if (msgdoc->_store->contacts()) mu_contacts_add (msgdoc->_store->contacts(), contact->address, contact->name, + msgdoc->_personal, mu_msg_get_date(msgdoc->_msg)); } } + +static void +each_contact_check_if_personal (MuMsgContact *contact, MsgDoc *msgdoc) +{ + GSList *cur; + + if (msgdoc->_personal || !contact->address) + return; + + for (cur = msgdoc->_my_addresses; cur; cur = g_slist_next (cur)) { + //g_print ("%s <=> %s\n", contact->address, (const char*)cur->data); + if (g_ascii_strcasecmp (contact->address, (const char*)cur->data) == 0) + msgdoc->_personal = TRUE; + } +} + + + #define MU_STRING_CHUNK_SIZE 8192 Xapian::Document new_doc_from_message (MuStore *store, MuMsg *msg) { Xapian::Document doc; - MsgDoc docinfo = {&doc, msg, store, 0}; + MsgDoc docinfo = {&doc, msg, store, 0, FALSE, NULL}; docinfo._strchunk = g_string_chunk_new (MU_STRING_CHUNK_SIZE); mu_msg_field_foreach ((MuMsgFieldForeachFunc)add_terms_values, &docinfo); - /* also store the contact-info as separate terms */ + + /* determine whether this is 'personal' email, ie. one of my + * e-mail addresses is explicitly mentioned -- it's not a + * mailing list message. Callback will update docinfo->_personal */ + if (store->my_addresses()) { + docinfo._my_addresses = store->my_addresses(); + mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact_check_if_personal, + &docinfo); + } + + /* also store the contact-info as separate terms, and add it + * to the cache */ mu_msg_contact_foreach (msg, (MuMsgContactForeachFunc)each_contact_info, &docinfo); diff --git a/lib/mu-store.h b/lib/mu-store.h index 38be7d6b..431c0fe4 100644 --- a/lib/mu-store.h +++ b/lib/mu-store.h @@ -36,12 +36,15 @@ typedef struct _MuStore MuStore; * * @param path the path to the database * @param ccachepath path where to cache the contacts information, or NULL + * @param my_addresses, array of strings with regexps for my e-mail addresses (or NULL) + * (used for the contactac information) * @param err to receive error info or NULL. err->code is MuError value * * @return a new MuStore object with ref count == 1, or NULL in case * of error; free with mu_store_unref */ -MuStore* mu_store_new_writable (const char *xpath, const char *ccachepath, +MuStore* mu_store_new_writable (const char *xpath, + const char *ccachepath, const char **my_addresses, gboolean rebuild, GError **err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; diff --git a/lib/tests/test-mu-store.c b/lib/tests/test-mu-store.c index 6b15bf0a..510608a9 100644 --- a/lib/tests/test-mu-store.c +++ b/lib/tests/test-mu-store.c @@ -44,7 +44,7 @@ test_mu_store_new_destroy (void) g_assert (tmpdir); err = NULL; - store = mu_store_new_writable (tmpdir, NULL, FALSE, &err); + store = mu_store_new_writable (tmpdir, NULL, NULL, FALSE, &err); g_assert (store); g_assert (err == NULL); @@ -68,7 +68,7 @@ test_mu_store_version (void) g_assert (tmpdir); err = NULL; - store = mu_store_new_writable (tmpdir, NULL, FALSE, &err); + store = mu_store_new_writable (tmpdir, NULL, NULL, FALSE, &err); g_assert (store); mu_store_unref (store); store = mu_store_new_read_only (tmpdir, &err); @@ -95,7 +95,7 @@ test_mu_store_store_msg_and_count (void) tmpdir = test_mu_common_get_random_tmpdir(); g_assert (tmpdir); - store = mu_store_new_writable (tmpdir, NULL, FALSE, NULL); + store = mu_store_new_writable (tmpdir, NULL, NULL, FALSE, NULL); g_assert (store); g_assert_cmpuint (0,==,mu_store_count (store, NULL)); @@ -151,7 +151,7 @@ test_mu_store_store_msg_remove_and_count (void) tmpdir = test_mu_common_get_random_tmpdir(); g_assert (tmpdir); - store = mu_store_new_writable (tmpdir, NULL, FALSE, NULL); + store = mu_store_new_writable (tmpdir, NULL, NULL, FALSE, NULL); g_assert (store); g_assert_cmpuint (0,==,mu_store_count (store, NULL));