diff options
Diffstat (limited to 'camel/providers')
-rw-r--r-- | camel/providers/mbox/Makefile.am | 2 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 25 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.h | 9 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-search.c | 353 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-search.h | 11 |
5 files changed, 28 insertions, 372 deletions
diff --git a/camel/providers/mbox/Makefile.am b/camel/providers/mbox/Makefile.am index 0597a68a57..defd6925cc 100644 --- a/camel/providers/mbox/Makefile.am +++ b/camel/providers/mbox/Makefile.am @@ -25,13 +25,11 @@ libcamelmbox_la_SOURCES = \ camel-mbox-folder.c \ camel-mbox-provider.c \ camel-mbox-store.c \ - camel-mbox-search.c \ camel-mbox-summary.c libcamelmboxinclude_HEADERS = \ camel-mbox-folder.h \ camel-mbox-store.h \ - camel-mbox-search.h \ camel-mbox-summary.h libcamelmbox_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir) diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 0b776db81c..7a0151f515 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -40,7 +40,6 @@ #include "string-utils.h" #include "camel-stream-fs.h" #include "camel-mbox-summary.h" -#include "camel-mbox-search.h" #include "camel-data-wrapper.h" #include "camel-mime-message.h" @@ -82,6 +81,8 @@ static const gchar *_get_message_uid (CamelFolder *folder, CamelMimeMessage *mes GPtrArray *summary_get_message_info (CamelFolder *folder, int first, int count); static const CamelMessageInfo *mbox_summary_get_by_uid(CamelFolder *f, const char *uid); +static GList *mbox_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); + static void mbox_finalize (GtkObject *object); static void @@ -114,7 +115,7 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class) #endif camel_folder_class->get_message_by_uid = mbox_get_message_by_uid; - camel_folder_class->search_by_expression = camel_mbox_folder_search_by_expression; + camel_folder_class->search_by_expression = mbox_search_by_expression; camel_folder_class->get_message_info = summary_get_message_info; camel_folder_class->summary_get_by_uid = mbox_summary_get_by_uid; @@ -187,6 +188,7 @@ mbox_init (CamelFolder *folder, CamelStore *parent_store, CAMEL_MESSAGE_SEEN; mbox_folder->summary = NULL; + mbox_folder->search = NULL; /* now set the name info */ g_free (mbox_folder->folder_file_path); @@ -247,6 +249,9 @@ mbox_close (CamelFolder *folder, gboolean expunge, CamelException *ex) camel_mbox_summary_save (mbox_folder->summary); camel_mbox_summary_unref (mbox_folder->summary); mbox_folder->summary = NULL; + if (mbox_folder->search) + gtk_object_unref((GtkObject *)mbox_folder->search); + mbox_folder->search = NULL; } @@ -945,3 +950,19 @@ mbox_summary_get_by_uid(CamelFolder *f, const char *uid) return (CamelMessageInfo *)camel_mbox_summary_uid(mbox_folder->summary, uid); } +static GList * +mbox_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) +{ + CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; + + if (mbox_folder->search == NULL) { + mbox_folder->search = camel_folder_search_new(); + } + + camel_folder_search_set_folder(mbox_folder->search, folder); + if (mbox_folder->summary) + camel_folder_search_set_summary(mbox_folder->search, mbox_folder->summary->messages); + camel_folder_search_set_body_index(mbox_folder->search, mbox_folder->index); + + return camel_folder_search_execute_expression(mbox_folder->search, expression, ex); +} diff --git a/camel/providers/mbox/camel-mbox-folder.h b/camel/providers/mbox/camel-mbox-folder.h index 24a336f8c9..d7dc361f14 100644 --- a/camel/providers/mbox/camel-mbox-folder.h +++ b/camel/providers/mbox/camel-mbox-folder.h @@ -34,8 +34,9 @@ extern "C" { #endif /* __cplusplus }*/ #include <gtk/gtk.h> -#include "camel-folder.h" -#include "libibex/ibex.h" +#include <camel/camel-folder.h> +#include <camel/camel-folder-search.h> +#include <libibex/ibex.h> #include "camel-mbox-summary.h" /* #include "camel-store.h" */ @@ -53,9 +54,9 @@ typedef struct { gchar *folder_dir_path; /* contains the subfolders */ gchar *index_file_path; /* index of body contents */ - ibex *index; /* index for this folder */ - + ibex *index; /* index for this folder */ CamelMboxSummary *summary; + CamelFolderSearch *search; /* used to run searches, we just use the real thing (tm) */ } CamelMboxFolder; diff --git a/camel/providers/mbox/camel-mbox-search.c b/camel/providers/mbox/camel-mbox-search.c deleted file mode 100644 index 412926ea2c..0000000000 --- a/camel/providers/mbox/camel-mbox-search.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright 2000 HelixCode (http://www.helixcode.com). - * - * Author : - * Michael Zucchi <notzed@helixcode.com> - - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <glib.h> -#include <stdio.h> -#include <time.h> -#include <string.h> - - -#include <camel/gmime-utils.h> -#include "camel/camel-mime-message.h" -#include "camel/camel-mime-part.h" -#include "camel/camel-stream.h" -#include "camel/camel-stream-fs.h" -#include "camel/camel.h" -#include "camel-mbox-folder.h" -#include "camel-mbox-summary.h" - -#include "camel-mbox-search.h" -#define HAVE_FILTER -#ifdef HAVE_FILTER -#include "e-sexp.h" - -#define HAVE_IBEX -#ifdef HAVE_IBEX -#include "ibex.h" -#endif - -#define p(x) /* parse debug */ -#define r(x) /* run debug */ -#define d(x) /* general debug */ - - -/* - - Matching operators: - - list = (body-contains string+) - bool = (body-contains string+) - Returns a list of all messages containing any of the strings in the message. - If within a match-all, then returns true for the current message. - - list = (match-all bool-expr) - Returns a list of all messages for which the bool expression is true. - The bool-expr is evaluated for each message in turn. - It is more efficient not to perform body-content comparisons inside a - match-all operator. - - int = (date-sent) - Returns a time_t of the date-sent of the message. - - bool = (header-contains string string+) - Returns true if the current message (inside a match-all operator) - has a header 'string1', which contains any of the following strings. -*/ - - -struct _searchcontext { - int id; /* id of this search */ - - CamelFolder *folder; - -#ifdef HAVE_IBEX - ibex *index; /* index of content for this folder */ -#endif - - CamelMboxSummary *summary; - - CamelMboxMessageInfo *message_current; /* when performing a (match operation */ -}; - -struct _glib_sux_donkeys { - int count; - GPtrArray *uids; -}; -/* or, store all unique values */ -static void -g_lib_sux_htor(char *key, int value, struct _glib_sux_donkeys *fuckup) -{ - g_ptr_array_add(fuckup->uids, key); -} - -static ESExpResult * -func_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - int i, j; - struct _searchcontext *ctx = data; - - if (ctx->message_current) { - int truth = FALSE; - - r = e_sexp_result_new(ESEXP_RES_BOOL); - if (ctx->index) { - for (i=0;i<argc && !truth;i++) { - if (argv[i]->type == ESEXP_RES_STRING) { - truth = ibex_find_name(ctx->index, ctx->message_current->info.uid, argv[i]->value.string); - } else { - g_warning("Invalid type passed to body-contains match function"); - } - } - } else { - g_warning("Cannot perform indexed query with no index"); - } - r->value.bool = truth; - } else { - r = e_sexp_result_new(ESEXP_RES_ARRAY_PTR); - - if (ctx->index) { - if (argc==1) { - /* common case */ - r->value.ptrarray = ibex_find(ctx->index, argv[0]->value.string); - } else { - GHashTable *ht = g_hash_table_new(g_str_hash, g_str_equal); - GPtrArray *pa; - struct _glib_sux_donkeys lambdafoo; - - /* this sux, perform an or operation on the result(s) of each word */ - for (i=0;i<argc;i++) { - if (argv[i]->type == ESEXP_RES_STRING) { - pa = ibex_find(ctx->index, argv[i]->value.string); - for (j=0;j<pa->len;j++) { - g_hash_table_insert(ht, g_ptr_array_index(pa, j), (void *)1); - } - g_ptr_array_free(pa, FALSE); - } - } - lambdafoo.uids = g_ptr_array_new(); - g_hash_table_foreach(ht, (GHFunc)g_lib_sux_htor, &lambdafoo); - r->value.ptrarray = lambdafoo.uids; - } - } else { - r->value.ptrarray = g_ptr_array_new(); - } - } - - return r; -} - -static ESExpResult * -func_date_sent(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - struct _searchcontext *ctx = data; - - r = e_sexp_result_new(ESEXP_RES_INT); - - if (ctx->message_current) { - g_warning("FIXME: implement date parsing ..."); - /* r->value.number = get_date(ctx->message_current); */ - } else { - r->value.number = time(0); - } - return r; -} - - -static ESExpResult * -func_match_all(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data) -{ - int i; - ESExpResult *r, *r1; - struct _searchcontext *ctx = data; - - if (argc>1) { - g_warning("match-all only takes a single argument, other arguments ignored"); - } - r = e_sexp_result_new(ESEXP_RES_ARRAY_PTR); - r->value.ptrarray = g_ptr_array_new(); - - for (i=0;i<ctx->summary->messages->len;i++) { - if (argc>0) { - ctx->message_current = g_ptr_array_index(ctx->summary->messages, i); - r1 = e_sexp_term_eval(f, argv[0]); - if (r1->type == ESEXP_RES_BOOL) { - if (r1->value.bool) - g_ptr_array_add(r->value.ptrarray, ctx->message_current->info.uid); - } else { - g_warning("invalid syntax, matches require a single bool result"); - } - e_sexp_result_free(r1); - } else { - g_ptr_array_add(r->value.ptrarray, ctx->message_current->info.uid); - } - } - ctx->message_current = NULL; - - return r; -} - -static ESExpResult * -func_header_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - struct _searchcontext *ctx = data; - int truth = FALSE; - - r(printf("executing header-contains\n")); - - /* are we inside a match-all? */ - if (ctx->message_current && argc>1 - && argv[0]->type == ESEXP_RES_STRING) { - char *headername, *header = NULL; - char strbuf[32]; - int i; - - /* only a subset of headers are supported .. */ - headername = argv[0]->value.string; - if (!strcasecmp(headername, "subject")) { - header = ctx->message_current->info.subject; - } else if (!strcasecmp(headername, "date")) { - sprintf(strbuf, "%d", (int)ctx->message_current->info.date_sent); - header = strbuf; - } else if (!strcasecmp(headername, "from")) { - header = ctx->message_current->info.from; - } else { - g_warning("Performing query on unknown header: %s", headername); - } - - if (header) { - for (i=1;i<argc && !truth;i++) { - if (argv[i]->type == ESEXP_RES_STRING - && strstr(header, argv[i]->value.string)) { - r(printf("%s got a match with %s of %s\n", ctx->message_current->info.uid, header, argv[i]->value.string)); - truth = TRUE; - break; - } - } - } - } - r = e_sexp_result_new(ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "body-contains", func_body_contains, 0 }, - { "date-sent", func_date_sent, 0 }, - { "match-all", (ESExpFunc *)func_match_all, 1 }, - { "header-contains", func_header_contains, 0 }, -}; - -GList *camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) -{ - int i; - struct _searchcontext *ctx; - GList *matches = NULL; - ESExp *f; - ESExpResult *r; - CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder; - - /* setup our expression evaluator */ - f = e_sexp_new(); - - ctx = g_malloc0(sizeof(*ctx)); - - /* setup out context */ - ctx->folder = folder; - ctx->summary = mbox_folder->summary; - - if (ctx->summary == NULL || camel_exception_get_id (ex)) { - printf ("Cannot get summary\n" - "Full description : %s\n", camel_exception_get_description (ex)); - g_free(ctx); - gtk_object_unref((GtkObject *)f); - return NULL; - } - - /* FIXME: the index should be global to the folder */ - ctx->message_current = NULL; - ctx->index = CAMEL_MBOX_FOLDER(folder)->index; - if (!ctx->index) { - g_warning("No folder index, searches will not function fully"); - } - - for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) { - if (symbols[i].type == 1) { - e_sexp_add_ifunction(f, 0, symbols[i].name, (ESExpIFunc *)symbols[i].func, ctx); - } else { - e_sexp_add_function(f, 0, symbols[i].name, symbols[i].func, ctx); - } - } - - e_sexp_input_text(f, expression, strlen(expression)); - e_sexp_parse(f); - r = e_sexp_eval(f); - - /* now create a folder summary to return?? */ - if (r - && r->type == ESEXP_RES_ARRAY_PTR) { - d(printf("got result ...\n")); - for (i=0;i<r->value.ptrarray->len;i++) { - d(printf("adding match: %s\n", (char *)g_ptr_array_index(r->value.ptrarray, i))); - matches = g_list_prepend(matches, g_strdup(g_ptr_array_index(r->value.ptrarray, i))); - } - e_sexp_result_free(r); - } else { - printf("no result!\n"); - } - - gtk_object_unref((GtkObject *)f); - - g_free(ctx); - - return matches; -} - -#else /* HAVE_FILTER */ - -int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expression, - CamelSearchFunc *func, void *data, CamelException *ex) -{ - return -1; -} - -gboolean camel_mbox_folder_search_complete(CamelFolder *folder, int searchid, int wait, CamelException *ex) -{ - return TRUE; -} - -void camel_mbox_folder_search_cancel(CamelFolder *folder, int searchid, CamelException *ex) -{ - /* empty */ -} - -#endif /*! HAVE_FILTER */ diff --git a/camel/providers/mbox/camel-mbox-search.h b/camel/providers/mbox/camel-mbox-search.h deleted file mode 100644 index f99d922252..0000000000 --- a/camel/providers/mbox/camel-mbox-search.h +++ /dev/null @@ -1,11 +0,0 @@ - -#ifndef _CAMEL_MBOX_SEARCH_H -#define _CAMEL_MBOX_SEARCH_H - -#include <glib.h> -#include "camel-mbox-folder.h" - -GList *camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); - -#endif /* ! _CAMEL_MBOX_SEARCH_H */ - |