[evolution-kolab/EDS_IMAPX_nobuild] updated IMAPX files as of EDS commit a9a45e9a213cc5c99c3c0cdb7dc452d180b5306d
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/EDS_IMAPX_nobuild] updated IMAPX files as of EDS commit a9a45e9a213cc5c99c3c0cdb7dc452d180b5306d
- Date: Fri, 3 Feb 2012 15:53:58 +0000 (UTC)
commit 9deb5e0bbfe739f92a5184a15e4fc90eda773485
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Fri Feb 3 16:07:23 2012 +0100
updated IMAPX files as of EDS commit a9a45e9a213cc5c99c3c0cdb7dc452d180b5306d
* updated the local IMAPX code from upstream
* now at EDS commit
a9a45e9a213cc5c99c3c0cdb7dc452d180b5306d
src/camel/providers/imapx/camel-imapx-command.c | 2 +-
src/camel/providers/imapx/camel-imapx-folder.c | 49 +++
src/camel/providers/imapx/camel-imapx-provider.c | 5 +-
src/camel/providers/imapx/camel-imapx-server.c | 311 +++++++++++++++++++-
src/camel/providers/imapx/camel-imapx-server.h | 8 +-
src/camel/providers/imapx/camel-imapx-settings.c | 65 ++++
src/camel/providers/imapx/camel-imapx-settings.h | 5 +
.../providers/imapx/camel-imapx-store-summary.c | 2 +-
src/camel/providers/imapx/camel-imapx-store.c | 15 +-
src/camel/providers/imapx/camel-imapx-utils.c | 14 +-
10 files changed, 458 insertions(+), 18 deletions(-)
---
diff --git a/src/camel/providers/imapx/camel-imapx-command.c b/src/camel/providers/imapx/camel-imapx-command.c
index e8ba3cd..f648a03 100644
--- a/src/camel/providers/imapx/camel-imapx-command.c
+++ b/src/camel/providers/imapx/camel-imapx-command.c
@@ -276,7 +276,7 @@ camel_imapx_command_addv (CamelIMAPXCommand *ic,
s = va_arg (ap, gchar *);
c(ic->is->tagprefix, "got string '%s'\n", g_str_has_prefix (format, "LOGIN") ? "***" : s);
output_string:
- if (*s) {
+ if (s && *s) {
guchar mask = imapx_is_mask (s);
if (mask & IMAPX_TYPE_ATOM_CHAR)
diff --git a/src/camel/providers/imapx/camel-imapx-folder.c b/src/camel/providers/imapx/camel-imapx-folder.c
index 6197a57..81a4a66 100644
--- a/src/camel/providers/imapx/camel-imapx-folder.c
+++ b/src/camel/providers/imapx/camel-imapx-folder.c
@@ -378,6 +378,42 @@ imapx_expunge_sync (CamelFolder *folder,
return FALSE;
}
+static gboolean
+imapx_fetch_messages_sync (CamelFolder *folder,
+ CamelFetchType type,
+ int limit,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStore *parent_store;
+ CamelIMAPXStore *istore;
+ CamelIMAPXServer *server;
+ gboolean success = FALSE;
+
+ parent_store = camel_folder_get_parent_store (folder);
+ istore = CAMEL_IMAPX_STORE (parent_store);
+
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (istore))) {
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_UNAVAILABLE,
+ _("You must be working online to complete this operation"));
+ return FALSE;
+ }
+
+ if (!camel_service_connect_sync ((CamelService *) istore, error))
+ return FALSE;
+
+ server = camel_imapx_store_get_server (istore, camel_folder_get_full_name (folder), cancellable, error);
+ if (server != NULL) {
+ success = camel_imapx_server_fetch_messages (server, folder, type, limit, cancellable, error);
+ camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
+ g_object_unref (server);
+ }
+
+ return success;
+}
+
static CamelMimeMessage *
imapx_get_message_sync (CamelFolder *folder,
const gchar *uid,
@@ -447,6 +483,17 @@ imapx_get_message_sync (CamelFolder *folder,
}
static gboolean
+imapx_purge_message_cache_sync (CamelFolder *folder,
+ gchar *start_uid,
+ gchar *end_uid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* Not Implemented for now. */
+ return TRUE;
+}
+
+static gboolean
imapx_refresh_info_sync (CamelFolder *folder,
GCancellable *cancellable,
GError **error)
@@ -607,7 +654,9 @@ camel_imapx_folder_class_init (CamelIMAPXFolderClass *class)
folder_class->get_filename = imapx_get_filename;
folder_class->append_message_sync = imapx_append_message_sync;
folder_class->expunge_sync = imapx_expunge_sync;
+ folder_class->fetch_messages_sync = imapx_fetch_messages_sync;
folder_class->get_message_sync = imapx_get_message_sync;
+ folder_class->purge_message_cache_sync = imapx_purge_message_cache_sync;
folder_class->refresh_info_sync = imapx_refresh_info_sync;
folder_class->synchronize_sync = imapx_synchronize_sync;
folder_class->synchronize_message_sync = imapx_synchronize_message_sync;
diff --git a/src/camel/providers/imapx/camel-imapx-provider.c b/src/camel/providers/imapx/camel-imapx-provider.c
index 116ff13..6179e84 100644
--- a/src/camel/providers/imapx/camel-imapx-provider.c
+++ b/src/camel/providers/imapx/camel-imapx-provider.c
@@ -98,7 +98,10 @@ static CamelProvider imapx_provider = {
"mail",
CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
- CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL,
+ CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL|
+ CAMEL_PROVIDER_SUPPORTS_MOBILE_DEVICES |
+ CAMEL_PROVIDER_SUPPORTS_BATCH_FETCH |
+ CAMEL_PROVIDER_SUPPORTS_PURGE_MESSAGE_CACHE,
CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
index 9eff1c2..a21e534 100644
--- a/src/camel/providers/imapx/camel-imapx-server.c
+++ b/src/camel/providers/imapx/camel-imapx-server.c
@@ -102,6 +102,8 @@ struct _RefreshInfoData {
/* used for building uidset stuff */
gint index;
gint last_index;
+ gint fetch_msg_limit;
+ CamelFetchType fetch_type;
gboolean update_unseen;
struct _uidset_state uidset;
/* changes during refresh */
@@ -207,6 +209,7 @@ enum {
IMAPX_JOB_CREATE_FOLDER = 1 << 11,
IMAPX_JOB_DELETE_FOLDER = 1 << 12,
IMAPX_JOB_RENAME_FOLDER = 1 << 13,
+ IMAPX_JOB_FETCH_MESSAGES = 1 << 14,
};
/* Operations on the store (folder_tree) will have highest priority as we know for sure they are sync
@@ -558,10 +561,10 @@ duplicate_fetch_or_refresh (CamelIMAPXServer *is,
if (!ic->job)
return FALSE;
- if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO)))
+ if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES)))
return FALSE;
- if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO, NULL)) {
+ if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES, NULL)) {
c(is->tagprefix, "Not yet sending duplicate fetch/refresh %s command\n", ic->name);
return TRUE;
}
@@ -967,7 +970,7 @@ imapx_get_uid_from_index (CamelFolderSummary *summary,
guint id)
{
GPtrArray *array;
- gchar *uid;
+ gchar *uid = NULL;
g_return_val_if_fail (summary != NULL, NULL);
@@ -1204,7 +1207,7 @@ imapx_untagged (CamelIMAPXServer *is,
}
if ((finfo->got & FETCH_FLAGS) && !(finfo->got & FETCH_HEADER)) {
- CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO, NULL);
+ CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES, NULL);
/* This is either a refresh_info job, check to see if it is and update
* if so, otherwise it must've been an unsolicited response, so update
* the summary to match */
@@ -1277,7 +1280,7 @@ imapx_untagged (CamelIMAPXServer *is,
}
if ((finfo->got & (FETCH_HEADER | FETCH_UID)) == (FETCH_HEADER | FETCH_UID)) {
- CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO, NULL);
+ CamelIMAPXJob *job = imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES | IMAPX_JOB_REFRESH_INFO | IMAPX_JOB_FETCH_MESSAGES, NULL);
/* This must be a refresh info job as well, but it has asked for
* new messages to be added to the index */
@@ -2087,6 +2090,7 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is,
data = g_slice_new0 (RefreshInfoData);
data->changes = camel_folder_change_info_new ();
data->update_unseen = update_unseen;
+ data->fetch_msg_limit = -1;
job = camel_imapx_job_new (cancellable);
job->type = IMAPX_JOB_FETCH_NEW_MESSAGES;
@@ -3609,12 +3613,25 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
RefreshInfoData *data;
gint i;
gboolean success = TRUE;
+ CamelSettings *settings;
+ CamelService *service;
+ guint batch_count;
+ gboolean mobile_mode;
data = camel_imapx_job_get_data (job);
g_return_val_if_fail (data != NULL, FALSE);
+ service = CAMEL_SERVICE (is->store);
+ settings = camel_service_get_settings (service);
+
+ batch_count = camel_imapx_settings_get_batch_fetch_count (
+ CAMEL_IMAPX_SETTINGS (settings));
+ mobile_mode = camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (settings));
+
i = data->index;
+ //printf("%s: Mobile mode: %d Fetch Count %d\n", camel_folder_get_display_name (job->folder), mobile_mode, batch_count);
if (camel_imapx_command_set_error_if_failed (ic, error)) {
g_prefix_error (
error, "%s: ",
@@ -3632,6 +3649,9 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
camel_folder_change_info_clear (data->changes);
if (i < data->infos->len) {
+ int total = camel_folder_summary_count (job->folder->summary);
+ int fetch_limit = data->fetch_msg_limit;
+
camel_imapx_command_unref (ic);
ic = camel_imapx_command_new (
@@ -3639,9 +3659,15 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
ic->complete = imapx_command_step_fetch_done;
ic->job = job;
ic->pri = job->pri - 1;
+
+ //printf("Total: %d: %d, %d, %d\n", total, fetch_limit, i, data->last_index);
data->last_index = i;
- for (; i < data->infos->len; i++) {
+ /* If its mobile client and when total=0 (new account setup) fetch only one batch of mails,
+ * on futher attempts download all new mails as per the limit. */
+ //printf("Total: %d: %d\n", total, fetch_limit);
+ for (; i < data->infos->len && (!mobile_mode || (total && i == 0) || ((fetch_limit != -1 && i < fetch_limit) || (fetch_limit == -1 && i < batch_count))); i++) {
+
gint res;
struct _refresh_info *r = &g_array_index (data->infos, struct _refresh_info, i);
@@ -3656,9 +3682,11 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
}
}
- data->index = i;
+ //printf("Existing : %d Gonna fetch in %s for %d/%d\n", total, camel_folder_get_full_name(job->folder), i, data->infos->len);
+ data->index = data->infos->len;
if (imapx_uidset_done (&data->uidset, ic)) {
camel_imapx_command_add (ic, " (RFC822.SIZE RFC822.HEADER)");
+
imapx_command_queue (is, ic);
return TRUE;
}
@@ -3732,6 +3760,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
guint uidset_size;
gint i;
gboolean success = TRUE;
+ gboolean mobile_mode;
data = camel_imapx_job_get_data (job);
g_return_val_if_fail (data != NULL, FALSE);
@@ -3741,6 +3770,8 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
uidset_size = camel_imapx_settings_get_batch_fetch_count (
CAMEL_IMAPX_SETTINGS (settings));
+ mobile_mode = camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (settings));
if (camel_imapx_command_set_error_if_failed (ic, error)) {
g_prefix_error (
@@ -3887,8 +3918,12 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
}
/* There's no sane way to get the server-side unseen count on the
- * select mailbox. So just work it out from the flags */
- ((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
+ * select mailbox. So just work it out from the flags if its not in
+ * mobile mode. In mobile mode we would have this filled up already
+ * with a STATUS command.
+ **/
+ if (!mobile_mode)
+ ((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
g_array_free (data->infos, TRUE);
imapx_unregister_job (is, job);
@@ -3903,6 +3938,7 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
{
CamelIMAPXCommand *ic;
RefreshInfoData *data;
+ gchar *uid = imapx_get_uid_from_index (job->folder->summary, 0);
data = camel_imapx_job_get_data (job);
g_return_if_fail (data != NULL);
@@ -3914,14 +3950,17 @@ imapx_job_scan_changes_start (CamelIMAPXJob *job,
_("Scanning for changed messages in %s"),
camel_folder_get_display_name (job->folder));
+ e('E', "Scanning from %s in %s\n", uid, camel_folder_get_full_name (job->folder));
ic = camel_imapx_command_new (
is, "FETCH", job->folder,
- "UID FETCH 1:* (UID FLAGS)");
+ "UID FETCH %s:* (UID FLAGS)", uid ? uid : "1");
+
ic->job = job;
ic->complete = imapx_job_scan_changes_done;
ic->pri = job->pri;
data->infos = g_array_new (0, 0, sizeof (struct _refresh_info));
imapx_command_queue (is, ic);
+ g_free (uid);
}
static gboolean
@@ -4043,6 +4082,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
_("Fetching summary information for new messages in %s"),
camel_folder_get_display_name (folder));
+ //printf("Fetch order: %d/%d\n", fetch_order, CAMEL_SORT_DESCENDING);
if (diff > uidset_size || fetch_order == CAMEL_SORT_DESCENDING) {
ic = camel_imapx_command_new (
is, "FETCH", job->folder,
@@ -4069,6 +4109,125 @@ imapx_job_fetch_new_messages_start (CamelIMAPXJob *job,
}
static void
+imapx_job_fetch_messages_start (CamelIMAPXJob *job,
+ CamelIMAPXServer *is)
+{
+ CamelIMAPXCommand *ic;
+ CamelFolder *folder = job->folder;
+ CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
+ guint32 total, diff;
+ gchar *start_uid = NULL, *end_uid = NULL;
+ CamelFetchType ftype;
+ gint fetch_limit;
+ CamelSortType fetch_order;
+ CamelService *service;
+ CamelSettings *settings;
+ guint uidset_size;
+ RefreshInfoData *data;
+
+ data = camel_imapx_job_get_data (job);
+ g_return_if_fail (data != NULL);
+
+ service = CAMEL_SERVICE (is->store);
+ settings = camel_service_get_settings (service);
+
+ fetch_order = camel_imapx_settings_get_fetch_order (
+ CAMEL_IMAPX_SETTINGS (settings));
+
+ total = camel_folder_summary_count (folder->summary);
+ diff = ifolder->exists_on_server - total;
+
+ ftype = data->fetch_type;
+ fetch_limit = data->fetch_msg_limit;
+
+ uidset_size = camel_imapx_settings_get_batch_fetch_count (
+ CAMEL_IMAPX_SETTINGS (settings));
+
+ if (ftype == CAMEL_FETCH_NEW_MESSAGES ||
+ (ftype == CAMEL_FETCH_OLD_MESSAGES && total <=0 )) {
+
+ char *uid;
+
+ if (total > 0) {
+ /* This means that we are fetching limited number of new mails */
+ uid = g_strdup_printf("%d", total);
+ } else {
+ /* For empty accounts, we always fetch the specified number of new mails independent of
+ * being asked to fetch old or new.
+ */
+ uid = g_strdup ("1");
+ }
+
+ if (ftype == CAMEL_FETCH_NEW_MESSAGES) {
+ /* We need to issue Status command to get the total unread count */
+ ic = camel_imapx_command_new (
+ is, "STATUS", NULL,
+ "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder);
+
+ ic->job = job;
+ ic->pri = job->pri;
+
+ imapx_command_run_sync (is, ic, job->cancellable, &job->error);
+
+ if (ic->job->error == NULL)
+ camel_imapx_command_set_error_if_failed (ic, &ic->job->error);
+
+ g_prefix_error (
+ &ic->job->error, "%s: ",
+ _("Error while fetching messages"));
+
+ camel_imapx_command_unref (ic);
+ }
+
+ camel_operation_push_message (
+ job->cancellable, _("Fetching summary information for %d messages in %s"),
+ data->fetch_msg_limit, camel_folder_get_full_name (folder));
+ /* New account and fetching old messages, we would return just the limited number of newest messages */
+ ic = camel_imapx_command_new (
+ is, "FETCH", job->folder,
+ "UID FETCH %s:* (UID FLAGS)", uid);
+
+ imapx_uidset_init (&data->uidset, uidset_size, 0);
+ data->infos = g_array_new (0, 0, sizeof (struct _refresh_info));
+ ic->pri = job->pri;
+
+ if (fetch_order == CAMEL_SORT_DESCENDING)
+ ic->complete = imapx_command_fetch_new_uids_done;
+ else
+ ic->complete = imapx_command_step_fetch_done;
+
+ g_free (uid);
+ ic->job = job;
+ imapx_command_queue (is, ic);
+
+ return;
+ } else if (ftype == CAMEL_FETCH_OLD_MESSAGES && total > 0) {
+ unsigned long long uidl;
+ start_uid = imapx_get_uid_from_index (folder->summary, 0);
+ uidl = strtoull(start_uid, NULL, 10);
+ end_uid = g_strdup_printf("%lld", (((int)uidl)-fetch_limit > 0) ? (uidl-fetch_limit) : 1);
+
+ camel_operation_push_message(
+ job->cancellable, _("Fetching summary information for %d messages in %s"),
+ data->fetch_msg_limit, camel_folder_get_full_name (folder));
+
+ ic = camel_imapx_command_new (is, "FETCH", job->folder,
+ "UID FETCH %s:%s (RFC822.SIZE RFC822.HEADER FLAGS)", start_uid, end_uid);
+ ic->pri = job->pri;
+ ic->complete = imapx_command_fetch_new_messages_done;
+
+ g_free (start_uid);
+ g_free (end_uid);
+
+ ic->job = job;
+ imapx_command_queue (is, ic);
+
+ } else {
+ g_error ("Shouldn't reach here. Incorrect fetch type");
+ }
+}
+
+static void
imapx_job_refresh_info_start (CamelIMAPXJob *job,
CamelIMAPXServer *is)
{
@@ -4080,6 +4239,14 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
gboolean need_rescan = FALSE;
gboolean is_selected = FALSE;
gboolean can_qresync = FALSE;
+ CamelService *service;
+ CamelSettings *settings;
+ gboolean mobile_mode;
+
+ service = CAMEL_SERVICE (is->store);
+ settings = camel_service_get_settings (service);
+ mobile_mode = camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (settings));
full_name = camel_folder_get_full_name (folder);
@@ -4178,6 +4345,31 @@ imapx_job_refresh_info_start (CamelIMAPXJob *job,
(!is_selected && isum->modseq != ifolder->modseq_on_server))
need_rescan = TRUE;
+ } else if (mobile_mode) {
+ /* We need to issue Status command to get the total unread count */
+ CamelIMAPXCommand *ic;
+
+ ic = camel_imapx_command_new (
+ is, "STATUS", NULL,
+ "STATUS %f (MESSAGES UNSEEN UIDVALIDITY UIDNEXT)", folder);
+
+ ic->job = job;
+ ic->pri = job->pri;
+
+ imapx_command_run_sync (is, ic, job->cancellable, &job->error);
+
+ if (ic->job->error == NULL)
+ camel_imapx_command_set_error_if_failed (ic, &ic->job->error);
+
+ g_prefix_error (
+ &ic->job->error, "%s: ",
+ _("Error refreshing folder"));
+
+ if (ic->job->error != NULL) {
+ camel_imapx_command_unref (ic);
+ goto done;
+ }
+ camel_imapx_command_unref (ic);
}
if (is->use_qresync && isum->modseq && ifolder->uidvalidity_on_server)
@@ -4681,11 +4873,19 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
CamelStore *parent_store;
SyncChangesData *data;
const gchar *full_name;
+ CamelService *service;
+ CamelSettings *settings;
+ gboolean mobile_mode;
gboolean success = TRUE;
data = camel_imapx_job_get_data (job);
g_return_val_if_fail (data != NULL, FALSE);
+ service = CAMEL_SERVICE (is->store);
+ settings = camel_service_get_settings (service);
+ mobile_mode = camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (settings));
+
job->commands--;
full_name = camel_folder_get_full_name (job->folder);
@@ -4741,7 +4941,8 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
if (si->total != camel_folder_summary_get_saved_count (job->folder->summary) ||
si->unread != camel_folder_summary_get_unread_count (job->folder->summary)) {
si->total = camel_folder_summary_get_saved_count (job->folder->summary);
- si->unread = camel_folder_summary_get_unread_count (job->folder->summary);
+ if (!mobile_mode) /* Don't mess with server's unread count in mobile mode, as what we have downloaded is little */
+ si->unread = camel_folder_summary_get_unread_count (job->folder->summary);
camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);
}
@@ -5551,7 +5752,9 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is,
QUEUE_LOCK (is);
- if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL)) {
+ /* Both RefreshInfo and Fetch messages can't operate simultaneously */
+ if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
+ imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
QUEUE_UNLOCK (is);
return TRUE;
}
@@ -6004,6 +6207,90 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is,
return success;
}
+static gboolean
+imapx_job_fetch_messages_matches (CamelIMAPXJob *job,
+ CamelFolder *folder,
+ const gchar *uid)
+{
+ return (folder == job->folder);
+}
+
+gboolean
+camel_imapx_server_fetch_messages (CamelIMAPXServer *is,
+ CamelFolder *folder,
+ CamelFetchType type,
+ int limit,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelIMAPXJob *job;
+ RefreshInfoData *data;
+ gboolean registered = TRUE;
+ const gchar *full_name;
+ gboolean success = TRUE;
+ unsigned long long firstuid, newfirstuid;
+ gchar *uid;
+ int old_len;
+
+ old_len = camel_folder_summary_count (folder->summary);
+ uid = imapx_get_uid_from_index (folder->summary, 0);
+ firstuid = strtoull(uid, NULL, 10);
+ g_free (uid);
+
+ QUEUE_LOCK (is);
+
+ /* Both RefreshInfo and Fetch messages can't operate simultaneously */
+ if (imapx_is_job_in_queue (is, folder, IMAPX_JOB_REFRESH_INFO, NULL) ||
+ imapx_is_job_in_queue (is, folder, IMAPX_JOB_FETCH_MESSAGES, NULL)) {
+ QUEUE_UNLOCK (is);
+ return TRUE;
+ }
+
+
+ data = g_slice_new0 (RefreshInfoData);
+ data->changes = camel_folder_change_info_new ();
+ data->fetch_msg_limit = limit;
+ data->fetch_type = type;
+
+ job = camel_imapx_job_new (cancellable);
+ job->type = IMAPX_JOB_FETCH_MESSAGES;
+ job->start = imapx_job_fetch_messages_start;
+ job->matches = imapx_job_fetch_messages_matches;
+ job->folder = folder;
+ job->pri = IMAPX_PRIORITY_NEW_MESSAGES;
+
+ full_name = camel_folder_get_full_name (folder);
+
+ if (g_ascii_strcasecmp(full_name, "INBOX") == 0)
+ job->pri += 10;
+
+ camel_imapx_job_set_data (
+ job, data, (GDestroyNotify) refresh_info_data_free);
+
+ registered = imapx_register_job (is, job, error);
+
+ QUEUE_UNLOCK (is);
+
+ success = registered && camel_imapx_job_run (job, is, error);
+
+ if (success && camel_folder_change_info_changed (data->changes) && camel_folder_change_info_changed (data->changes))
+ camel_folder_changed (folder, data->changes);
+
+ uid = imapx_get_uid_from_index (folder->summary, 0);
+ newfirstuid = strtoull(uid, NULL, 10);
+ g_free (uid);
+
+ camel_imapx_job_unref (job);
+
+ if (type == CAMEL_FETCH_OLD_MESSAGES && firstuid == newfirstuid)
+ return FALSE; /* No more old messages */
+ else if (type == CAMEL_FETCH_NEW_MESSAGES &&
+ old_len == camel_folder_summary_count (folder->summary))
+ return FALSE; /* No more new messages */
+
+ return TRUE;
+}
+
gboolean
camel_imapx_server_rename_folder (CamelIMAPXServer *is,
const gchar *old_name,
diff --git a/src/camel/providers/imapx/camel-imapx-server.h b/src/camel/providers/imapx/camel-imapx-server.h
index d6921b3..a7ce0a3 100644
--- a/src/camel/providers/imapx/camel-imapx-server.h
+++ b/src/camel/providers/imapx/camel-imapx-server.h
@@ -53,7 +53,6 @@ G_BEGIN_DECLS
typedef struct _CamelIMAPXServer CamelIMAPXServer;
typedef struct _CamelIMAPXServerClass CamelIMAPXServerClass;
-typedef struct _CamelIMAPXCommand CamelIMAPXCommand;
typedef struct _CamelIMAPXIdle CamelIMAPXIdle;
struct _IMAPXJobQueueInfo;
@@ -167,6 +166,13 @@ gboolean camel_imapx_server_expunge (CamelIMAPXServer *is,
CamelFolder *folder,
GCancellable *cancellable,
GError **error);
+gboolean camel_imapx_server_fetch_messages
+ (CamelIMAPXServer *is,
+ CamelFolder *folder,
+ CamelFetchType type,
+ int limit,
+ GCancellable *cancellable,
+ GError **error);
gboolean camel_imapx_server_noop (CamelIMAPXServer *is,
CamelFolder *folder,
GCancellable *cancellable,
diff --git a/src/camel/providers/imapx/camel-imapx-settings.c b/src/camel/providers/imapx/camel-imapx-settings.c
index 0ffdc46..2b4c333 100644
--- a/src/camel/providers/imapx/camel-imapx-settings.c
+++ b/src/camel/providers/imapx/camel-imapx-settings.c
@@ -38,6 +38,7 @@ struct _CamelIMAPXSettingsPrivate {
gboolean filter_junk;
gboolean filter_junk_inbox;
gboolean use_idle;
+ gboolean use_mobile_mode;
gboolean use_namespace;
gboolean use_qresync;
gboolean use_shell_command;
@@ -57,6 +58,7 @@ enum {
PROP_FILTER_JUNK,
PROP_FILTER_JUNK_INBOX,
PROP_HOST,
+ PROP_MOBILE_MODE,
PROP_NAMESPACE,
PROP_PORT,
PROP_SECURITY_METHOD,
@@ -137,6 +139,12 @@ imapx_settings_set_property (GObject *object,
g_value_get_string (value));
return;
+ case PROP_MOBILE_MODE:
+ camel_imapx_settings_set_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (object),
+ g_value_get_boolean (value));
+ return;
+
case PROP_NAMESPACE:
camel_imapx_settings_set_namespace (
CAMEL_IMAPX_SETTINGS (object),
@@ -271,6 +279,13 @@ imapx_settings_get_property (GObject *object,
CAMEL_NETWORK_SETTINGS (object)));
return;
+ case PROP_MOBILE_MODE:
+ g_value_set_boolean (
+ value,
+ camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (object)));
+ return;
+
case PROP_NAMESPACE:
g_value_take_string (
value,
@@ -468,6 +483,18 @@ camel_imapx_settings_class_init (CamelIMAPXSettingsClass *class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (
+ object_class,
+ PROP_MOBILE_MODE,
+ g_param_spec_boolean (
+ "mobile-mode",
+ "Mobile Mode",
+ "Mobile mode which adjusts the IMAPX for Mobile clients",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
/* Inherited from CamelNetworkSettings. */
g_object_class_override_property (
object_class,
@@ -877,6 +904,44 @@ camel_imapx_settings_set_filter_junk_inbox (CamelIMAPXSettings *settings,
}
/**
+ * camel_imapx_settings_get_mobile_mode:
+ * @settings: a #CamelIMAPXSettings
+ *
+ * Returns whether the backend is operating in mobile mode.
+ *
+ * Since: 3.2
+ **/
+gboolean
+camel_imapx_settings_get_mobile_mode (CamelIMAPXSettings *settings)
+{
+ g_return_val_if_fail (
+ CAMEL_IS_IMAPX_SETTINGS (settings),
+ CAMEL_SORT_ASCENDING);
+
+ return settings->priv->use_mobile_mode;
+}
+
+/**
+ * camel_imapx_settings_set_mobile_mode:
+ * @settings: a #CamelIMAPXSettings
+ * @mobile_mode: whether to operate in mobile mode.
+ *
+ * Sets the mode of operation as mobile or not for the backend.
+ *
+ * Since: 3.2
+ **/
+void
+camel_imapx_settings_set_mobile_mode (CamelIMAPXSettings *settings,
+ gboolean mobile_mode)
+{
+ g_return_if_fail (CAMEL_IS_IMAPX_SETTINGS (settings));
+
+ settings->priv->use_mobile_mode = mobile_mode;
+
+ g_object_notify (G_OBJECT (settings), "mobile-mode");
+}
+
+/**
* camel_imapx_settings_get_namespace:
* @settings: a #CamelIMAPXSettings
*
diff --git a/src/camel/providers/imapx/camel-imapx-settings.h b/src/camel/providers/imapx/camel-imapx-settings.h
index 54f810c..bffa560 100644
--- a/src/camel/providers/imapx/camel-imapx-settings.h
+++ b/src/camel/providers/imapx/camel-imapx-settings.h
@@ -91,6 +91,11 @@ gboolean camel_imapx_settings_get_filter_junk_inbox
void camel_imapx_settings_set_filter_junk_inbox
(CamelIMAPXSettings *settings,
gboolean filter_junk_inbox);
+gboolean camel_imapx_settings_get_mobile_mode
+ (CamelIMAPXSettings *settings);
+void camel_imapx_settings_set_mobile_mode
+ (CamelIMAPXSettings *settings,
+ gboolean mobile);
const gchar * camel_imapx_settings_get_namespace
(CamelIMAPXSettings *settings);
gchar * camel_imapx_settings_dup_namespace
diff --git a/src/camel/providers/imapx/camel-imapx-store-summary.c b/src/camel/providers/imapx/camel-imapx-store-summary.c
index f881a17..c764106 100644
--- a/src/camel/providers/imapx/camel-imapx-store-summary.c
+++ b/src/camel/providers/imapx/camel-imapx-store-summary.c
@@ -146,7 +146,7 @@ camel_imapx_store_summary_full_to_path (CamelIMAPXStoreSummary *s,
p = path = g_strdup (full_name);
- if (dir_sep != '/') {
+ if (dir_sep && dir_sep != '/') {
while (*p) {
if (*p == '/')
*p = dir_sep;
diff --git a/src/camel/providers/imapx/camel-imapx-store.c b/src/camel/providers/imapx/camel-imapx-store.c
index 0ed414d..3b1d55c 100644
--- a/src/camel/providers/imapx/camel-imapx-store.c
+++ b/src/camel/providers/imapx/camel-imapx-store.c
@@ -392,6 +392,13 @@ fill_fi (CamelStore *store,
guint32 flags)
{
CamelFolder *folder;
+ CamelService *service = (CamelService *)store;
+ CamelSettings *settings;
+ gboolean mobile_mode;
+
+ settings = camel_service_get_settings (service);
+ mobile_mode = camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (settings));
folder = camel_object_bag_peek (store->folders, fi->full_name);
if (folder) {
@@ -402,7 +409,13 @@ fill_fi (CamelStore *store,
else
ims = (CamelIMAPXSummary *) camel_imapx_summary_new (folder);
- fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
+ /* Mobile clients would still love to see the total unread of actual mails
+ * than what they just have downloaded. So we override that information by giving
+ * what the server has instead of what we have downloaded. */
+ if (mobile_mode)
+ fi->unread = ((CamelIMAPXFolder *) folder)->unread_on_server;
+ else
+ fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
if (!folder->summary)
diff --git a/src/camel/providers/imapx/camel-imapx-utils.c b/src/camel/providers/imapx/camel-imapx-utils.c
index b04c01e..a7a0825 100644
--- a/src/camel/providers/imapx/camel-imapx-utils.c
+++ b/src/camel/providers/imapx/camel-imapx-utils.c
@@ -22,6 +22,7 @@
#include <string.h>
#include "camel-imapx-folder.h"
+#include "camel-imapx-settings.h"
#include "camel-imapx-stream.h"
#include "camel-imapx-summary.h"
#include "camel-imapx-store.h"
@@ -310,9 +311,16 @@ imapx_update_store_summary (CamelFolder *folder)
CamelStoreInfo *si;
CamelStore *parent_store;
const gchar *full_name;
+ CamelService *service;
+ CamelSettings *settings;
+ gboolean mobile_mode;
full_name = camel_folder_get_full_name (folder);
parent_store = camel_folder_get_parent_store (folder);
+ service = CAMEL_SERVICE (parent_store);
+ settings = camel_service_get_settings (service);
+ mobile_mode = camel_imapx_settings_get_mobile_mode (
+ CAMEL_IMAPX_SETTINGS (settings));
si = camel_store_summary_path ((CamelStoreSummary *) ((CamelIMAPXStore *) parent_store)->summary, full_name);
if (si) {
@@ -322,7 +330,11 @@ imapx_update_store_summary (CamelFolder *folder)
unread = camel_folder_summary_get_unread_count (folder->summary);
if (si->unread != unread || si->total != total) {
- si->unread = unread;
+
+ if (!mobile_mode)
+ si->unread = unread;
+ else
+ si->unread = ((CamelIMAPXFolder *)folder)->unread_on_server;
si->total = total;
camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]