[evolution-data-server/email-factory] Add support to mobile extension of POP/IMAP and implement the new APIs.
- From: Srinivasa Ragavan <sragavan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/email-factory] Add support to mobile extension of POP/IMAP and implement the new APIs.
- Date: Tue, 7 Jun 2011 12:22:14 +0000 (UTC)
commit 647eef1456debf637fe4389dd711435a410a003b
Author: Srinivasa Ragavan <sragavan gnome org>
Date: Tue Jun 7 23:19:27 2011 +0530
Add support to mobile extension of POP/IMAP and implement the new APIs.
mail/daemon/e-mail-data-folder.c | 59 +++++++++++++++++++++++++++
mail/daemon/e-mail-data-folder.xml | 4 ++
mail/daemon/e-mail-data-session.c | 49 +++++++++++++++++++++++
mail/daemon/e-mail-data-session.xml | 6 +++
mail/daemon/mail-ops.c | 75 +++++++++++++++++++++++++++++++++-
mail/daemon/mail-ops.h | 2 +-
mail/daemon/mail-send-recv.c | 4 +-
7 files changed, 193 insertions(+), 6 deletions(-)
---
diff --git a/mail/daemon/e-mail-data-folder.c b/mail/daemon/e-mail-data-folder.c
index 4636381..fd092de 100644
--- a/mail/daemon/e-mail-data-folder.c
+++ b/mail/daemon/e-mail-data-folder.c
@@ -1617,6 +1617,64 @@ ps_done (gboolean success, gpointer sdata, GError *error)
g_free (data);
}
+/* Fetch Old messages */
+typedef struct _email_folder_fetch_data {
+ EMailDataFolder *mfolder;
+ EGdbusFolderCF *object;
+ GDBusMethodInvocation *invocation;
+ gint count;
+}EMailFolderFetchData;
+
+
+static gboolean
+fetch_old_operate (CamelFolder *folder, gpointer sdata, GError **error)
+{
+ EMailFolderFetchData *data = (EMailFolderFetchData *)sdata;
+
+ return camel_folder_fetch_old_messages (folder, data->count, error);
+}
+
+static void
+fetch_old_done (gboolean success, gpointer sdata, GError *error)
+{
+ EMailFolderFetchData *data = (EMailFolderFetchData *)sdata;
+ EMailDataFolderPrivate *priv = DATA_FOLDER_PRIVATE(data->mfolder);
+
+ if (error && error->message) {
+ g_warning ("Fetch old messages failed: %s: %s\n", priv->path, error->message);
+ g_dbus_method_invocation_return_gerror (data->invocation, error);
+ ipc(printf("Fetch old messages: %s failed: %s\n", priv->path, error->message));
+ return;
+ }
+
+
+ egdbus_folder_cf_complete_fetch_old_messages (data->object, data->invocation, success);
+
+ ipc(printf("Fetch old messages: %s success: %d\n", priv->path, success));
+
+ g_free (data);
+}
+
+
+
+static
+gboolean
+impl_Mail_fetchOldMessages (EGdbusFolderCF *object, GDBusMethodInvocation *invocation, int count, EMailDataFolder *mfolder)
+{
+ EMailFolderFetchData *data;
+ EMailDataFolderPrivate *priv = DATA_FOLDER_PRIVATE(mfolder);
+
+ data = g_new0 (EMailFolderFetchData, 1);
+ data->mfolder = mfolder;
+ data->invocation = invocation;
+ data->object = object;
+ data->count = count;
+
+ mail_operate_on_folder (priv->folder, fetch_old_operate, fetch_old_done, data);
+
+ return TRUE;
+}
+
static gboolean
impl_Mail_prepareSummary (EGdbusFolderCF *object, GDBusMethodInvocation *invocation, EMailDataFolder *mfolder)
{
@@ -1674,6 +1732,7 @@ e_mail_data_folder_init (EMailDataFolder *self)
g_signal_connect (priv->gdbus_object, "handle-get-message-info", G_CALLBACK (impl_Mail_getMessageInfo), self);
g_signal_connect (priv->gdbus_object, "handle-transfer-messages-to", G_CALLBACK (impl_Mail_transferMessagesTo), self);
g_signal_connect (priv->gdbus_object, "handle-prepare-summary", G_CALLBACK (impl_Mail_prepareSummary), self);
+ g_signal_connect (priv->gdbus_object, "handle-fetch-old-messages", G_CALLBACK (impl_Mail_fetchOldMessages), self);
}
diff --git a/mail/daemon/e-mail-data-folder.xml b/mail/daemon/e-mail-data-folder.xml
index 1161eaf..ff9bcac 100644
--- a/mail/daemon/e-mail-data-folder.xml
+++ b/mail/daemon/e-mail-data-folder.xml
@@ -130,6 +130,10 @@
<arg name="uid" type="s" direction="in"/>
<arg name="message" type="s" direction="out"/>
</method>
+ <method name="fetchOldMessages">
+ <arg name="count" type="i" direction="in"/>
+ <arg name="success" type="b" direction="out"/>
+ </method>
<method name="searchByExpression">
<arg name="expression" type="s" direction="in"/>
<arg name="uids" type="as" direction="out"/>
diff --git a/mail/daemon/e-mail-data-session.c b/mail/daemon/e-mail-data-session.c
index 8be36b6..00913d8 100644
--- a/mail/daemon/e-mail-data-session.c
+++ b/mail/daemon/e-mail-data-session.c
@@ -7,6 +7,8 @@
#include <camel/camel.h>
#include <gio/gio.h>
#include "mail-ops.h"
+#include "mail-tools.h"
+#include "mail-send-recv.h"
#include "utils.h"
#include <libedataserver/e-account-list.h>
#include <libedataserverui/e-passwords.h>
@@ -381,6 +383,52 @@ impl_Mail_fetchAccount (EGdbusSessionCS *object, GDBusMethodInvocation *invocati
return TRUE;
}
+static void
+fetch_old_messages_done (gboolean still_more, EMailGetStoreData *data)
+{
+ ipc(printf("Done: Fetch old messages in POP: %d\n", still_more));
+ egdbus_session_cs_complete_fetch_old_messages (data->object, data->invocation, still_more);
+
+ g_free (data);
+}
+
+static gboolean
+impl_Mail_fetchOldMessages (EGdbusSessionCS *object, GDBusMethodInvocation *invocation, char *uid, int count, EMailDataSession *msession)
+{
+ EIterator *iter;
+ EAccountList *accounts;
+ EAccount *account;
+ EMailGetStoreData *data = g_new0(EMailGetStoreData, 1);
+
+ data->invocation = invocation;
+ data->msession = msession;
+ data->object = object;
+
+ accounts = e_get_account_list ();
+ for (iter = e_list_get_iterator ((EList *)accounts);
+ e_iterator_is_valid (iter);
+ e_iterator_next (iter)) {
+ account = (EAccount *) e_iterator_get (iter);
+ if (account->uid && strcmp (account->uid, uid) == 0) {
+ const gchar *uri;
+ gboolean keep_on_server;
+
+ uri = e_account_get_string (
+ account, E_ACCOUNT_SOURCE_URL);
+ keep_on_server = e_account_get_bool (
+ account, E_ACCOUNT_SOURCE_KEEP_ON_SERVER);
+ mail_fetch_mail (uri, keep_on_server,
+ E_FILTER_SOURCE_INCOMING,
+ NULL, count,
+ NULL, NULL,
+ NULL, NULL,
+ (void (*)(const gchar *, void *)) fetch_old_messages_done, data);
+ }
+ }
+
+ return TRUE;
+}
+
static gboolean
impl_Mail_cancelOperations (EGdbusSessionCS *object, GDBusMethodInvocation *invocation, EMailDataSession *msession)
{
@@ -453,6 +501,7 @@ e_mail_data_session_init (EMailDataSession *self)
g_signal_connect (priv->gdbus_object, "handle-add-password", G_CALLBACK (impl_Mail_addPassword), self);
g_signal_connect (priv->gdbus_object, "handle-send-receive", G_CALLBACK (impl_Mail_sendReceive), self);
g_signal_connect (priv->gdbus_object, "handle-fetch-account", G_CALLBACK (impl_Mail_fetchAccount), self);
+ g_signal_connect (priv->gdbus_object, "handle-fetch-old-messages", G_CALLBACK (impl_Mail_fetchOldMessages), self);
g_signal_connect (priv->gdbus_object, "handle-cancel-operations", G_CALLBACK (impl_Mail_cancelOperations), self);
priv->stores_lock = g_mutex_new ();
diff --git a/mail/daemon/e-mail-data-session.xml b/mail/daemon/e-mail-data-session.xml
index 793a7f6..731fe7e 100644
--- a/mail/daemon/e-mail-data-session.xml
+++ b/mail/daemon/e-mail-data-session.xml
@@ -45,6 +45,12 @@
<method name="fetchAccount">
<arg name="uid" type="s" direction="in"/>
</method>
+
+ <method name="fetchOldMessages">
+ <arg name="uid" type="s" direction="in"/>
+ <arg name="count" type="i" direction="in"/>
+ <arg name="success" type="b" direction="out"/>
+ </method>
<method name="cancelOperations">
</method>
diff --git a/mail/daemon/mail-ops.c b/mail/daemon/mail-ops.c
index 70b06ba..fbc53a5 100644
--- a/mail/daemon/mail-ops.c
+++ b/mail/daemon/mail-ops.c
@@ -49,6 +49,10 @@
/* XXX Make this a preprocessor definition. */
const gchar *x_mailer = "Evolution Mail Data Server 0.1 ";
+/* POP is a non storage store, and has to be sequential between same accounts. We'll use this to lock it*/
+static GStaticMutex pop3_hash_lock = G_STATIC_MUTEX_INIT;
+static GHashTable *pop3_hash = NULL;
+
/* used for both just filtering a folder + uid's, and for filtering a whole folder */
/* used both for fetching mail, and for filtering mail */
struct _filter_mail_msg {
@@ -69,6 +73,8 @@ struct _fetch_mail_msg {
CamelOperation *cancel; /* we have our own cancellation struct, the other should be empty */
gint keep; /* keep on server? */
+ gint more;
+ gboolean still_more;
gchar *source_uri;
@@ -217,6 +223,54 @@ mail_filter_junk (CamelFolder *folder, GPtrArray *uids)
#endif
/* ********************************************************************** */
+static void
+my_mutex_free (GMutex *lock)
+{
+ g_mutex_free (lock);
+}
+
+static GHashTable *
+get_pop3_hash ()
+{
+ g_static_mutex_lock (&pop3_hash_lock);
+ if (!pop3_hash)
+ pop3_hash = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)my_mutex_free);
+
+ g_static_mutex_unlock (&pop3_hash_lock);
+
+ return pop3_hash;
+}
+
+static void
+pop3_fetch_lock (const char *source)
+{
+ GMutex *lock;
+ GHashTable *hash = get_pop3_hash();
+
+ g_static_mutex_lock (&pop3_hash_lock);
+ lock = g_hash_table_lookup (hash, source);
+ if (!lock) {
+ lock = g_mutex_new();
+ g_hash_table_insert (hash, g_strdup(source), lock);
+ }
+ g_static_mutex_unlock (&pop3_hash_lock);
+
+ g_mutex_lock (lock);
+}
+
+static void
+pop3_fetch_unlock (const char *source)
+{
+ GMutex *lock;
+ GHashTable *hash = get_pop3_hash();
+
+ g_static_mutex_lock (&pop3_hash_lock);
+ /* lock can't disappear from hash */
+ lock = g_hash_table_lookup (hash, source);
+ g_static_mutex_unlock (&pop3_hash_lock);
+
+ g_mutex_unlock (lock);
+}
/* Temporary workaround for various issues. Gone before 0.11 */
static gchar *
@@ -332,6 +386,8 @@ fetch_mail_exec (struct _fetch_mail_msg *m)
} else {
CamelFolder *folder;
+ /* This is a account level lock to ensure that no two same accounts get fetched at the same time */
+ pop3_fetch_lock (m->source_uri);
folder = fm->source_folder =
mail_tool_get_inbox (m->source_uri, &fm->base.error);
@@ -341,6 +397,11 @@ fetch_mail_exec (struct _fetch_mail_msg *m)
CamelUIDCache *cache = NULL;
CamelStore *parent_store;
gchar *cachename;
+
+ if (m->more) {
+ printf("Fetching %d old messages\n", m->more);
+ m->still_more = camel_folder_fetch_old_messages(folder, m->more, &fm->base.error);
+ }
parent_store = camel_folder_get_parent_store (folder);
cachename = uid_cachename_hack (parent_store);
@@ -356,6 +417,7 @@ fetch_mail_exec (struct _fetch_mail_msg *m)
folder_uids = camel_folder_get_uids (folder);
cache_uids = camel_uid_cache_get_new_uids (cache, folder_uids);
+ printf("Gonna cache uids: %d\n", cache_uids->len);
if (cache_uids) {
/* need to copy this, sigh */
fm->source_uids = uids = g_ptr_array_new ();
@@ -402,6 +464,8 @@ fetch_mail_exec (struct _fetch_mail_msg *m)
g_object_unref (fm->source_folder);
fm->source_folder = NULL;
}
+
+ pop3_fetch_unlock(m->source_uri);
}
fail:
if (m->cancel)
@@ -419,8 +483,12 @@ fail:
static void
fetch_mail_done (struct _fetch_mail_msg *m)
{
- if (m->done)
- m->done (m->source_uri, m->data);
+ if (m->done) {
+ if (m->more)
+ m->done (m->still_more, m->data);
+ else
+ m->done (m->source_uri, m->data);
+ }
}
static void
@@ -443,7 +511,7 @@ static MailMsgInfo fetch_mail_info = {
/* ouch, a 'do everything' interface ... */
void
-mail_fetch_mail (const gchar *source, gint keep, const gchar *type, CamelOperation *cancel,
+mail_fetch_mail (const gchar *source, gint keep, const gchar *type, CamelOperation *cancel, gint more,
CamelFilterGetFolderFunc get_folder, gpointer get_data,
CamelFilterStatusFunc *status, gpointer status_data,
void (*done)(const gchar *source, gpointer data), gpointer data)
@@ -452,6 +520,7 @@ mail_fetch_mail (const gchar *source, gint keep, const gchar *type, CamelOperati
struct _filter_mail_msg *fm;
m = mail_msg_new (&fetch_mail_info);
+ m->more = more;
fm = (struct _filter_mail_msg *)m;
m->source_uri = g_strdup (source);
fm->delete = !keep;
diff --git a/mail/daemon/mail-ops.h b/mail/daemon/mail-ops.h
index 99a371c..2e82f7a 100644
--- a/mail/daemon/mail-ops.h
+++ b/mail/daemon/mail-ops.h
@@ -139,7 +139,7 @@ void mail_send_queue (CamelFolder *queue, const gchar *destination,
gpointer data);
void mail_fetch_mail (const gchar *source, gint keep,
- const gchar *type, CamelOperation *cancel,
+ const gchar *type, CamelOperation *cancel, gint more,
CamelFilterGetFolderFunc get_folder, gpointer get_data,
CamelFilterStatusFunc *status, gpointer status_data,
void (*done)(const gchar *source, gpointer data),
diff --git a/mail/daemon/mail-send-recv.c b/mail/daemon/mail-send-recv.c
index 6b218f3..e623548 100644
--- a/mail/daemon/mail-send-recv.c
+++ b/mail/daemon/mail-send-recv.c
@@ -1018,7 +1018,7 @@ mail_send_receive (GtkWindow *parent)
case SEND_RECEIVE:
mail_fetch_mail(info->uri, info->keep_on_server,
E_FILTER_SOURCE_INCOMING,
- info->cancel,
+ info->cancel, 0,
receive_get_folder, info,
receive_status, info,
receive_done, info);
@@ -1252,7 +1252,7 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
case SEND_RECEIVE:
mail_fetch_mail (info->uri, info->keep_on_server,
E_FILTER_SOURCE_INCOMING,
- info->cancel,
+ info->cancel, 0,
receive_get_folder, info,
receive_status, info,
receive_done, info);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]