[evolution-data-server] Fetch message summary - imapx.
- From: Chenthill Palanisamy <pchen src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Fetch message summary - imapx.
- Date: Fri, 27 Nov 2009 13:12:16 +0000 (UTC)
commit ac78d476d1a2afe1fe874351964afa7c08548f51
Author: Chenthill Palanisamy <pchenthill novell com>
Date: Fri Nov 27 18:37:51 2009 +0530
Fetch message summary - imapx.
camel/providers/imapx/camel-imapx-folder.c | 87 ++++++++++++++++--
camel/providers/imapx/camel-imapx-folder.h | 7 +-
camel/providers/imapx/camel-imapx-server.c | 134 +++++++++++++++++-----------
camel/providers/imapx/test-imapx.c | 3 +
4 files changed, 167 insertions(+), 64 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index 4549414..4a07856 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -35,6 +35,7 @@
#include "camel/camel-data-cache.h"
#include "camel/camel-session.h"
#include "camel/camel-file-utils.h"
+#include "camel-folder-search.h"
#include "camel-imapx-store.h"
#include "camel-imapx-folder.h"
@@ -53,18 +54,32 @@
static CamelFolderClass *parent_class;
CamelFolder *
-camel_imapx_folder_new(CamelStore *store, const gchar *path, const gchar *raw)
+camel_imapx_folder_new(CamelStore *store, const gchar *path, const gchar *folder_name)
{
CamelFolder *folder;
+ CamelIMAPXFolder *ifolder;
+ const gchar *short_name;
+ gchar *summary_file;
d(printf("opening imap folder '%s'\n", path));
+ short_name = strrchr (folder_name, '/');
+ if (short_name)
+ short_name++;
+ else
+ short_name = folder_name;
+
folder = CAMEL_FOLDER (camel_object_new (CAMEL_IMAPX_FOLDER_TYPE));
- camel_folder_construct(folder, store, path, path);
+ camel_folder_construct(folder, store, folder_name, short_name);
+ ifolder = folder;
+
+ ((CamelIMAPXFolder *)folder)->raw_name = g_strdup(folder_name);
- ((CamelIMAPXFolder *)folder)->raw_name = g_strdup(raw);
+ summary_file = g_strdup_printf ("%s/summary", path);
+ folder->summary = camel_imapx_summary_new(folder, summary_file);
+ ifolder->search = camel_folder_search_new ();
- folder->summary = camel_imapx_summary_new(folder, raw);
+ g_free (summary_file);
return folder;
}
@@ -96,10 +111,13 @@ camel_imapx_folder_close(CamelIMAPXFolder *folder, CamelException *ex)
static void
imapx_refresh_info (CamelFolder *folder, CamelException *ex)
{
- CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+ CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
+
+ if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+ return;
- if (is->server)
- camel_imapx_server_refresh_info(is->server, folder, ex);
+ if (istore->server)
+ camel_imapx_server_refresh_info(istore->server, folder, ex);
}
@@ -212,10 +230,63 @@ info.state - 2 bit field in flags
*/
static void
+imapx_search_free (CamelFolder *folder, GPtrArray *uids)
+{
+ CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER(folder);
+
+ g_return_if_fail (ifolder->search);
+
+ camel_folder_search_free_result (ifolder->search, uids);
+}
+
+static GPtrArray *
+imapx_search_by_uids (CamelFolder *folder, const gchar *expression, GPtrArray *uids, CamelException *ex)
+{
+ CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER(folder);
+ GPtrArray *matches;
+
+ if (uids->len == 0)
+ return g_ptr_array_new();
+
+ camel_folder_search_set_folder(ifolder->search, folder);
+ matches = camel_folder_search_search(ifolder->search, expression, uids, ex);
+
+ return matches;
+}
+
+static guint32
+imapx_count_by_expression (CamelFolder *folder, const gchar *expression, CamelException *ex)
+{
+ CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER(folder);
+ guint32 matches;
+
+ camel_folder_search_set_folder (ifolder->search, folder);
+ matches = camel_folder_search_count (ifolder->search, expression, ex);
+
+ return matches;
+}
+
+static GPtrArray *
+imapx_search_by_expression (CamelFolder *folder, const gchar *expression, CamelException *ex)
+{
+ CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER (folder);
+ GPtrArray *matches;
+
+ camel_folder_search_set_folder (ifolder->search, folder);
+ matches = camel_folder_search_search(ifolder->search, expression, NULL, ex);
+
+ return matches;
+}
+
+static void
imap_folder_class_init (CamelIMAPXFolderClass *klass)
{
((CamelFolderClass *)klass)->refresh_info = imapx_refresh_info;
((CamelFolderClass *)klass)->sync = imapx_sync;
+ ((CamelFolderClass *)klass)->search_by_expression = imapx_search_by_expression;
+ ((CamelFolderClass *)klass)->search_by_uids = imapx_search_by_uids;
+ ((CamelFolderClass *)klass)->count_by_expression = imapx_count_by_expression;
+ ((CamelFolderClass *)klass)->search_free = imapx_search_free;
((CamelFolderClass *)klass)->get_message = imapx_get_message;
((CamelFolderClass *)klass)->append_message = imapx_append_message;
@@ -225,7 +296,6 @@ static void
imap_folder_init(CamelObject *o, CamelObjectClass *klass)
{
CamelFolder *folder = (CamelFolder *)o;
- CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *)o;
folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY |
CAMEL_FOLDER_HAS_SEARCH_CAPABILITY);
@@ -239,7 +309,6 @@ imap_folder_init(CamelObject *o, CamelObjectClass *klass)
static void
imap_finalise(CamelObject *object)
{
- CamelIMAPXFolder *folder = (CamelIMAPXFolder *)object;
}
diff --git a/camel/providers/imapx/camel-imapx-folder.h b/camel/providers/imapx/camel-imapx-folder.h
index 95a8156..a6c3a6c 100644
--- a/camel/providers/imapx/camel-imapx-folder.h
+++ b/camel/providers/imapx/camel-imapx-folder.h
@@ -32,14 +32,15 @@ extern "C" {
#include <camel/camel-folder.h>
#define CAMEL_IMAPX_FOLDER_TYPE (camel_imapx_folder_get_type ())
-#define CAMEL_IMAPX_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_FOLDER_TYPE, CamelIMAPPFolder))
-#define CAMEL_IMAPX_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_FOLDER_TYPE, CamelIMAPPFolderClass))
-#define CAMEL_IS_IMAP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPX_FOLDER_TYPE))
+#define CAMEL_IMAPX_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPX_FOLDER_TYPE, CamelIMAPXFolder))
+#define CAMEL_IMAPX_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPX_FOLDER_TYPE, CamelIMAPXFolderClass))
+#define CAMEL_IS_IMAPX_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPX_FOLDER_TYPE))
typedef struct _CamelIMAPXFolder {
CamelFolder parent_object;
gchar *raw_name;
+ CamelFolderSearch *search;
// CamelChangeInfo *changes;
} CamelIMAPXFolder;
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 77ab12f..1ef16e5 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -33,6 +33,7 @@
#include <camel/camel-net-utils.h>
#include <camel/camel-tcp-stream-ssl.h>
#include <camel/camel-tcp-stream-raw.h>
+#include <camel/camel-db.h>
#include <camel/camel-sasl.h>
#include <camel/camel-i18n.h>
@@ -201,7 +202,7 @@ struct _CamelIMAPXJob {
gint last_index;
struct _uidset_state uidset;
/* changes during refresh */
-// CamelChangeInfo *changes;
+ CamelFolderChangeInfo *changes;
} refresh_info;
struct {
GPtrArray *infos;
@@ -1007,7 +1008,7 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
finfo = imap_parse_fetch(imap->stream, ex);
- //imap_dump_fetch(finfo);
+ imap_dump_fetch(finfo);
if ((finfo->got & (FETCH_BODY|FETCH_UID)) == (FETCH_BODY|FETCH_UID)) {
CamelIMAPXJob *job = imapx_find_job(imap, IMAPX_JOB_GET_MESSAGE, finfo->uid);
@@ -1829,16 +1830,28 @@ imapx_refresh_info_cmp(gconstpointer ap, gconstpointer bp)
}
/* skips over non-server uids (pending appends) */
-static const CamelMessageInfo *
-imapx_iterator_next(CamelIterator *iter, CamelException *ex)
+static guint
+imapx_index_next (CamelFolderSummary *s, guint index)
{
- const CamelMessageInfo *iterinfo;
+ guint count = 0;
- while ((iterinfo = camel_iterator_next(iter, NULL))
- && strchr(camel_message_info_uid(iterinfo), '-') != NULL)
- printf("Ignoring offline uid '%s'\n", camel_message_info_uid(iterinfo));
+ count = camel_folder_summary_count (s);
- return iterinfo;
+ while (index < count) {
+ const CamelMessageInfo *info;
+
+ index++;
+ info = camel_folder_summary_index (s, index);
+ if (!info)
+ continue;
+
+ if (info && (strchr(camel_message_info_uid(info), '-') != NULL)) {
+ printf("Ignoring offline uid '%s'\n", camel_message_info_uid(info));
+ } else
+ break;
+ }
+
+ return index;
}
static void
@@ -1848,9 +1861,9 @@ imapx_job_refresh_info_step_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
gint i = job->u.refresh_info.index;
GArray *infos = job->u.refresh_info.infos;
-/* if (camel_change_info_changed(job->u.refresh_info.changes))
+ if (camel_folder_change_info_changed(job->u.refresh_info.changes))
camel_object_trigger_event(job->folder, "folder_changed", job->u.refresh_info.changes);
- camel_change_info_clear(job->u.refresh_info.changes); */
+ camel_folder_change_info_clear(job->u.refresh_info.changes);
if (i<infos->len) {
ic = camel_imapx_command_new("FETCH", job->folder->full_name, "UID FETCH ");
@@ -1881,6 +1894,7 @@ imapx_job_refresh_info_step_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
}
}
+ camel_folder_summary_save_to_db (job->folder->summary, NULL);
for (i=0;i<infos->len;i++) {
struct _refresh_info *r = &g_array_index(infos, struct _refresh_info, i);
@@ -1923,11 +1937,13 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
if (ic->status->result == IMAP_OK) {
GCompareDataFunc uid_cmp = imapx_uid_cmp;
- CamelIterator *iter;
- const CamelMessageInfo *iterinfo;
+ const CamelMessageInfo *s_minfo = NULL;
CamelIMAPXMessageInfo *info;
CamelFolderSummary *s = job->folder->summary;
- gint i, count=0;
+ GSList *removed = NULL;
+ gboolean fetch_new = FALSE;
+ gint i;
+ guint j = 0, total = 0;
/* Here we do the typical sort/iterate/merge loop.
If the server flags dont match what we had, we modify our
@@ -1939,49 +1955,64 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
for all outstanding messages to be uploaded */
qsort(infos->data, infos->len, sizeof(struct _refresh_info), imapx_refresh_info_cmp);
-
- /*
- iter = camel_folder_summary_search(s, NULL, NULL, NULL, NULL);
- iterinfo = imapx_iterator_next(iter, NULL);
-
- for (i=0;i<infos->len;i++) {
+ total = camel_folder_summary_count (s);
+ s_minfo = camel_folder_summary_index (s, 0);
+
+ for (i=0; i<infos->len ; i++) {
struct _refresh_info *r = &g_array_index(infos, struct _refresh_info, i);
- while (iterinfo && uid_cmp(camel_message_info_uid(iterinfo), r->uid, s) < 0) {
- printf("Message %s vanished\n", iterinfo->uid);
-// camel_change_info_remove(job->u.refresh_info.changes, iterinfo);
- camel_folder_summary_remove(s, (CamelMessageInfo *)iterinfo);
- iterinfo = imapx_iterator_next(iter, NULL);
+ while (s_minfo && uid_cmp(camel_message_info_uid(s_minfo), r->uid, s) < 0) {
+ const char *uid = camel_message_info_uid (s_minfo);
+
+ camel_folder_change_info_remove_uid (job->u.refresh_info.changes, uid);
+ removed = g_slist_prepend (removed, (gpointer )uid);
+ camel_folder_summary_remove_uid_fast (s, s_minfo->uid);
+ j = imapx_index_next (s, j);
+ s_minfo = camel_folder_summary_index (s, j);
}
info = NULL;
- if (iterinfo && uid_cmp(iterinfo->uid, r->uid, s) == 0) {
+ if (s_minfo && uid_cmp(s_minfo->uid, r->uid, s) == 0) {
printf("already have '%s'\n", r->uid);
- info = (CamelIMAPXMessageInfo *)iterinfo;
-// if (info->server_flags != r->server_flags
-// && camel_message_info_set_flags((CamelMessageInfo *)info, info->server_flags ^ r->server_flags, r->server_flags))
-// camel_change_info_change(job->u.refresh_info.changes, iterinfo);
- iterinfo = imapx_iterator_next(iter, NULL);
+ info = (CamelIMAPXMessageInfo *)s_minfo;
+ if (info->server_flags != r->server_flags
+ && camel_message_info_set_flags((CamelMessageInfo *)info, info->server_flags ^ r->server_flags, r->server_flags))
+ camel_folder_change_info_change_uid (job->u.refresh_info.changes, camel_message_info_uid (s_minfo));
g_free(r->uid);
r->uid = NULL;
- } else {
- count++;
- }
+ } else
+ fetch_new = TRUE;
+
+ j = imapx_index_next (s, j);
+ s_minfo = camel_folder_summary_index (s, j);
+
+ if (j > total)
+ break;
}
- while (iterinfo) {
- printf("Message %s vanished\n", iterinfo->uid);
-// camel_change_info_remove(job->u.refresh_info.changes, iterinfo);
- camel_folder_summary_remove(s, (CamelMessageInfo *)iterinfo);
- iterinfo = imapx_iterator_next(iter, NULL);
- } */
+ while (j < total) {
+ s_minfo = camel_folder_summary_index (s, j);
+
+ if (!s_minfo) {
+ j++;
+ continue;
+ }
+
+ printf("Message %s vanished\n", s_minfo->uid);
+ camel_folder_change_info_remove_uid (job->u.refresh_info.changes, s_minfo->uid);
+ camel_folder_summary_remove_uid_fast (s, s_minfo->uid);
+ removed = g_slist_prepend (removed, s_minfo->uid);
+ j++;
+ }
-/* if (camel_change_info_changed(job->u.refresh_info.changes))
+ camel_db_delete_uids (is->store, s->folder->full_name, removed, NULL);
+
+ if (camel_folder_change_info_changed(job->u.refresh_info.changes))
camel_object_trigger_event(job->folder, "folder_changed", job->u.refresh_info.changes);
- camel_change_info_clear(job->u.refresh_info.changes);*/
+ camel_folder_change_info_clear(job->u.refresh_info.changes);
/* If we have any new messages, download their headers, but only a few (100?) at a time */
- if (count) {
+ if (fetch_new) {
imapx_uidset_init(&job->u.refresh_info.uidset, 100, 0);
imapx_job_refresh_info_step_done(is, ic);
return;
@@ -2005,14 +2036,13 @@ imapx_job_refresh_info_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
{
CamelIMAPXCommand *ic;
- // temp ... we shouldn't/dont want to force select? or do we?
- //imapx_select(is, job->folder);
- ic = camel_imapx_command_new("FETCH", job->folder->full_name,
+ /* Should we force a select here ? */
+ ic = camel_imapx_command_new ("FETCH", job->folder->full_name,
"FETCH 1:* (UID FLAGS)");
ic->job = job;
ic->complete = imapx_job_refresh_info_done;
- job->u.refresh_info.infos = g_array_new(0, 0, sizeof(struct _refresh_info));
- imapx_command_queue(is, ic);
+ job->u.refresh_info.infos = g_array_new (0, 0, sizeof(struct _refresh_info));
+ imapx_command_queue (is, ic);
}
/* ********************************************************************** */
@@ -2603,7 +2633,7 @@ fail:
}
#include "camel-imapx-store.h"
-
+/*
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static CamelIterator *threaditer;
static CamelFolder *threadfolder;
@@ -2615,7 +2645,7 @@ getmsgs(gpointer d)
const CamelMessageInfo *info;
CamelException ex = { 0 };
- /* FIXME: detach? */
+ /* FIXME: detach?
printf("Checking thread, downloading messages in the background ...\n");
@@ -2645,7 +2675,7 @@ getmsgs(gpointer d)
pthread_mutex_unlock(&lock);
return NULL;
-}
+} */
void
camel_imapx_server_refresh_info(CamelIMAPXServer *is, CamelFolder *folder, CamelException *ex)
@@ -2657,7 +2687,7 @@ camel_imapx_server_refresh_info(CamelIMAPXServer *is, CamelFolder *folder, Camel
job->start = imapx_job_refresh_info_start;
job->folder = folder;
job->ex = ex;
-// job->u.refresh_info.changes = camel_change_info_new(NULL);
+ job->u.refresh_info.changes = camel_folder_change_info_new();
imapx_run_job(is, job);
diff --git a/camel/providers/imapx/test-imapx.c b/camel/providers/imapx/test-imapx.c
index 3cf406f..f65ff6e 100644
--- a/camel/providers/imapx/test-imapx.c
+++ b/camel/providers/imapx/test-imapx.c
@@ -11,6 +11,7 @@ main (gint argc, gchar *argv [])
CamelException *ex;
gchar *uri = NULL;
CamelService *service;
+ CamelFolder *folder;
if (argc != 2) {
printf ("Pass the account url argument \n");
@@ -31,6 +32,8 @@ main (gint argc, gchar *argv [])
camel_service_connect (service, ex);
camel_store_get_folder_info ((CamelStore *)service, "", 3, NULL);
+ folder = camel_store_get_folder ((CamelStore *)service, "INBOX", 0, NULL);
+ camel_folder_refresh_info (folder, NULL);
while (1)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]