aboutsummaryrefslogtreecommitdiffstats
path: root/filter
diff options
context:
space:
mode:
authorNotZed <NotZed@HelixCode.com>2000-03-05 11:36:37 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-03-05 11:36:37 +0800
commit2485f10196f6611d28d428ff0f1b9a5ac9fe755e (patch)
treed232ef17603fc2fc2e3b05772efc72dce7bad4d0 /filter
parent48e373b1565b810bcf76642d9fc6c96f3a26a0b0 (diff)
downloadgsoc2013-evolution-2485f10196f6611d28d428ff0f1b9a5ac9fe755e.tar.gz
gsoc2013-evolution-2485f10196f6611d28d428ff0f1b9a5ac9fe755e.tar.zst
gsoc2013-evolution-2485f10196f6611d28d428ff0f1b9a5ac9fe755e.zip
Actually implement filtering, at least, from Inbox. Copy messages to
2000-03-04 NotZed <NotZed@HelixCode.com> * filter-driver.c (main): Actually implement filtering, at least, from Inbox. Copy messages to folder (in the same store only, so far), delete, and stop processing are implemented, and the logic to handle default processing. * filter-xml.c (load_optionvalue): Fix up a bug where we lost the name of the arg (ouch). * filter-xml.c: Wrapped printf's in debug macros. svn path=/trunk/; revision=2054
Diffstat (limited to 'filter')
-rw-r--r--filter/ChangeLog11
-rw-r--r--filter/filter-driver.c297
-rw-r--r--filter/filter-xml.c63
3 files changed, 276 insertions, 95 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index 7eec85d5ee..0c0e7b097b 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,3 +1,14 @@
+2000-03-04 NotZed <NotZed@HelixCode.com>
+
+ * filter-driver.c (main): Actually implement filtering, at least,
+ from Inbox. Copy messages to folder (in the same store only, so
+ far), delete, and stop processing are implemented, and the logic
+ to handle default processing.
+
+ * filter-xml.c (load_optionvalue): Fix up a bug where we lost the
+ name of the arg (ouch).
+ * filter-xml.c: Wrapped printf's in debug macros.
+
2000-03-02 NotZed <NotZed@HelixCode.com>
* filter-druid.c (object_destroy): Disconnect the list signal, so
diff --git a/filter/filter-driver.c b/filter/filter-driver.c
index eb852b3cc2..37509d0bc9 100644
--- a/filter/filter-driver.c
+++ b/filter/filter-driver.c
@@ -23,6 +23,31 @@
extern int filter_find_arg(FilterArg *a, char *name);
+struct exec_context {
+ GHashTable *globals; /* global variables */
+
+ GList *matches; /* all messages which match current rule */
+
+ GList *deleted; /* messages to be deleted */
+ GHashTable *terminated; /* messages for which processing is terminated */
+ GHashTable *processed; /* all messages that were processed in some way */
+
+ CamelSession *session;
+ CamelStore *store;
+ CamelFolder *folder; /* temporary input folder */
+ CamelException *ex;
+};
+
+/*
+
+ foreach rule
+ find matches
+
+ foreach action
+ get all matches
+
+ */
+
/*
splices ${cc} lines into a single string
*/
@@ -37,6 +62,8 @@ expand_variables(GString *out, char *source, GList *args, GHashTable *globals)
int len=0;
int ok = 0;
+ printf("expanding %s\n", source);
+
start = source;
while ( (newstart = strstr(start, "${"))
&& (end = strstr(newstart+2, "}")) ) {
@@ -47,6 +74,7 @@ expand_variables(GString *out, char *source, GList *args, GHashTable *globals)
}
memcpy(name, newstart+2, len);
name[len] = 0;
+ printf("looking for name '%s'\n", name);
argl = g_list_find_custom(args, name, (GCompareFunc) filter_find_arg);
if (argl) {
int i, count;
@@ -75,7 +103,7 @@ expand_variables(GString *out, char *source, GList *args, GHashTable *globals)
} else {
ok = 1;
tmp = g_strdup_printf("%.*s", end-start+1, start);
- printf("appending: %s\n", tmp);
+ printf("appending: '%s'\n", tmp);
g_string_append(out, tmp);
g_free(tmp);
}
@@ -90,7 +118,7 @@ expand_variables(GString *out, char *source, GList *args, GHashTable *globals)
build an expression for the filter
*/
static void
-expand_filter_option(GString *s, struct filter_option *op)
+expand_filter_option(GString *s, GString *action, struct filter_option *op)
{
GList *optionl;
FilterArg *arg;
@@ -106,25 +134,33 @@ expand_filter_option(GString *s, struct filter_option *op)
struct filter_optionrule *or = optionl->data;
if (or->rule->type == FILTER_XML_MATCH
|| or->rule->type == FILTER_XML_EXCEPT) {
+ if (or->args) {
+ arg = or->args->data;
+ if (arg) {
+ printf("arg = %s\n", arg->name);
+ }
+ }
expand_variables(s, or->rule->code, or->args, globals);
}
optionl = g_list_next(optionl);
}
g_string_append(s, ")");
-#if 0
+
+ g_string_append(action, "(begin ");
optionl = op->options;
while (optionl) {
struct filter_optionrule *or = optionl->data;
if (or->rule->type == FILTER_XML_ACTION) {
- g_string_append(s, or->rule->code);
- g_string_append(s, " ");
+ expand_variables(action, or->rule->code, or->args, globals);
+ g_string_append(action, " ");
}
optionl = g_list_next(optionl);
}
- g_string_append(s, ")))");
-#endif
+ g_string_append(action, ")");
+
printf("combined rule '%s'\n", s->str);
+ printf("combined action '%s'\n", action->str);
}
struct filter_optionrule *
@@ -144,86 +180,217 @@ find_optionrule(struct filter_option *option, char *name)
return NULL;
}
+static ESExpResult *
+do_delete(struct _ESExp *f, int argc, struct _ESExpResult **argv, struct exec_context *x)
+{
+ GList *m;
+
+ printf("doing delete\n");
+ m = x->matches;
+ while (m) {
+ printf(" %s\n", m->data);
+ x->deleted = g_list_append(x->deleted, g_strdup(m->data));
+ m = m->next;
+ }
+ return NULL;
+}
+
+static ESExpResult *
+do_forward(struct _ESExp *f, int argc, struct _ESExpResult **argv, struct exec_context *x)
+{
+ GList *m;
+
+ printf("doing forward on the following messages:\n");
+ m = x->matches;
+ while (m) {
+ printf(" %s\n", m->data);
+ m = m->next;
+ }
+ return NULL;
+}
+
+static ESExpResult *
+do_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, struct exec_context *x)
+{
+ GList *m;
+ int i;
+
+ printf("doing copy on the following messages to:");
+ for (i=0;i<argc;i++) {
+ if (argv[i]->type == ESEXP_RES_STRING) {
+ char *folder = argv[i]->value.string;
+ CamelFolder *outbox;
+
+ /* FIXME: this might have to find another store, based on
+ the folder as a url??? */
+ printf("opening outpbox %s\n", folder);
+ outbox = camel_store_get_folder (x->store, folder, x->ex);
+ if (!camel_folder_exists(outbox, x->ex)) {
+ camel_folder_create(outbox, x->ex);
+ }
+
+ camel_folder_open (outbox, FOLDER_OPEN_WRITE, x->ex);
+
+ m = x->matches;
+ while (m) {
+ CamelMimeMessage *mm;
+
+ printf("appending message %s\n", m->data);
+
+ mm = camel_folder_get_message_by_uid(x->folder, m->data, x->ex);
+ camel_folder_append_message(outbox, mm, x->ex);
+ gtk_object_unref((GtkObject *)mm);
+
+ printf(" %s\n", m->data);
+ m = m->next;
+ }
+ camel_folder_close (outbox, FALSE, x->ex);
+ }
+ }
+
+ return NULL;
+}
+
+static ESExpResult *
+do_stop(struct _ESExp *f, int argc, struct _ESExpResult **argv, struct exec_context *x)
+{
+ GList *m;
+
+ printf("doing stop on the following messages:\n");
+ m = x->matches;
+ while (m) {
+ printf(" %s\n", m->data);
+ g_hash_table_insert(x->terminated, g_strdup(m->data), (void *)1);
+ m = m->next;
+ }
+ return NULL;
+}
+
+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[] = {
+ { "delete", (ESExpFunc *)do_delete, 0 },
+ { "forward-to", (ESExpFunc *)do_forward, 0 },
+ { "copy-to", (ESExpFunc *)do_copy, 0 },
+ { "stop", (ESExpFunc *)do_stop, 0 },
+};
+
+static char *
+auth_callback(char *prompt, gboolean secret,
+ CamelService *service, char *item,
+ CamelException *ex)
+{
+ printf ("auth_callback called: %s\n", prompt);
+ return NULL;
+}
+
+static struct exec_context *
+start(void)
+{
+ struct exec_context *x;
+ char *store_url = "mbox:///tmp/evmail";
+
+ x = g_malloc0(sizeof(*x));
+
+ /* just hack up this for now */
+ x->ex = camel_exception_new ();
+ camel_provider_register_as_module ("../camel/providers/mbox/.libs/libcamelmbox.so.0");
+ x->session = camel_session_new (auth_callback);
+ x->store = camel_session_get_store (x->session, store_url, x->ex);
+ x->folder = camel_store_get_folder (x->store, "Inbox", x->ex);
+ camel_folder_open (x->folder, FOLDER_OPEN_READ, x->ex);
+ x->terminated = g_hash_table_new(g_str_hash, g_str_equal);
+ x->processed = g_hash_table_new(g_str_hash, g_str_equal);
+ return x;
+}
+
int main(int argc, char **argv)
{
ESExp *f;
ESExpResult *r;
GList *rules, *options, *options2;
- xmlDocPtr doc, out, optionset, filteroptions;
- GString *s;
+ xmlDocPtr doc, out;
+ GString *s, *a;
+ GList *all, *m;
+ struct exec_context *x;
+ int i;
+ ESExp *eval;
gnome_init("Test", "0.0", argc, argv);
-#if 0
- gdk_rgb_init ();
- gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
- gtk_widget_set_default_visual (gdk_rgb_get_visual ());
-
- create_dialogue();
-#endif
+ camel_init();
doc = xmlParseFile("filterdescription.xml");
rules = filter_load_ruleset(doc);
- options = filter_load_optionset(doc, rules);
- options2 = options;
+ options2 = filter_load_optionset(doc, rules);
+
out = xmlParseFile("saveoptions.xml");
options = filter_load_optionset(out, rules);
-#if 0
-#if 0
- option_current = options->data;
- fill_rules(list_global, rules, options->data, FILTER_XML_MATCH);
-#else
- option_current = NULL;
- fill_options(list_global, options2);
-#endif
- gtk_main();
+ x = start();
+
+ eval = e_sexp_new();
+ /* Load in builtin symbols? */
+ for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) {
+ if (symbols[i].type == 1) {
+ e_sexp_add_ifunction(eval, 0, symbols[i].name, (ESExpIFunc *)symbols[i].func, x);
+ } else {
+ e_sexp_add_function(eval, 0, symbols[i].name, symbols[i].func, x);
+ }
+ }
while (options) {
struct filter_option *fo = options->data;
- GList *optionrulel;
- optionrulel = fo->options;
- while (optionrulel) {
- struct filter_optionrule *or = optionrulel->data;
+ s = g_string_new("");
+ a = g_string_new("");
+ expand_filter_option(s, a, fo);
+
+ printf("searching expression %s\n", s->str);
+ x->matches = camel_folder_search_by_expression (x->folder, s->str, x->ex);
+
+ /* remove uid's for which processing is complete ... */
+ m = x->matches;
+ while (m) {
+ GList *n = m->next;
+
+ /* for all matching id's, so we can work out what to default */
+ if (g_hash_table_lookup(x->processed, m->data) == NULL) {
+ g_hash_table_insert(x->processed, g_strdup(m->data), (void *)1);
+ }
- printf("formatting rule: %s\n", or->rule->name);
+ if (g_hash_table_lookup(x->terminated, m->data)) {
+ printf("removing terminated message %s\n", m->data);
+ x->matches = g_list_remove_link(x->matches, m);
+ }
+ m = n;
+ }
- /*filter_description_text(or->rule->description, or->args);*/
- filter_description_html_write(or->rule->description, or->args, NULL, NULL);
+ printf("applying actions ... '%s'\n", a->str);
+ e_sexp_input_text(eval, a->str, strlen(a->str));
+ e_sexp_parse(eval);
+ r = e_sexp_eval(eval);
+ e_sexp_result_free(r);
- optionrulel = g_list_next(optionrulel);
- }
+ g_string_free(s, TRUE);
+ g_string_free(a, TRUE);
+
options = g_list_next(options);
}
- return 0;
-#endif
-
- s = g_string_new("");
- expand_filter_option(s, options->data);
- g_string_append(s, "");
-
- printf("total rule = '%s'\n", s->str);
-
- f = e_sexp_new();
- e_sexp_add_variable(f, 0, "sender", NULL);
- e_sexp_add_variable(f, 0, "receipient", NULL);
- e_sexp_add_variable(f, 0, "folder", NULL);
-
- /* simple functions */
- e_sexp_add_function(f, 0, "header-get", NULL, NULL);
- e_sexp_add_function(f, 0, "header-contains", NULL, NULL);
- e_sexp_add_function(f, 0, "copy-to", NULL, NULL);
-
- e_sexp_add_ifunction(f, 0, "set", NULL, NULL);
-
- /* control functions */
- e_sexp_add_ifunction(f, 0, "match-all", NULL, NULL);
- e_sexp_add_ifunction(f, 0, "match", NULL, NULL);
- e_sexp_add_ifunction(f, 0, "action", NULL, NULL);
- e_sexp_add_ifunction(f, 0, "except", NULL, NULL);
+ /* now apply 'default' rule */
+ all = camel_folder_get_uid_list(x->folder, x->ex);
+ m = all;
+ while (m) {
+ char *uid = m->data;
+ if (g_hash_table_lookup(x->processed, uid) == NULL) {
+ printf("Applying default rule to message %s\n", uid);
+ }
+ m = m->next;
+ }
+ g_list_free(all);
- e_sexp_input_text(f, s->str, strlen(s->str));
- e_sexp_parse(f);
-
+ return 0;
}
diff --git a/filter/filter-xml.c b/filter/filter-xml.c
index 83bfe06131..b25b1b77af 100644
--- a/filter/filter-xml.c
+++ b/filter/filter-xml.c
@@ -13,6 +13,8 @@
#include "filter-arg-types.h"
#include "filter-xml.h"
+#define d(x)
+
struct token_tab {
char *name;
enum filter_xml_token token;
@@ -74,10 +76,10 @@ detokenise(int token)
static xmlNodePtr
find_node(xmlNodePtr start, char *name)
{
- printf("trying to find node '%s'\n", name);
+ d(printf("trying to find node '%s'\n", name));
while (start && strcmp(start->name, name))
start = start->next;
- printf("node = %p\n", start);
+ d(printf("node = %p\n", start));
return start;
}
@@ -87,11 +89,11 @@ find_node_attr(xmlNodePtr start, char *name, char *attrname, char *attrvalue)
xmlNodePtr node;
char *s;
- printf("looking for node named %s with attribute %s=%s\n", name, attrname, attrvalue);
+ d(printf("looking for node named %s with attribute %s=%s\n", name, attrname, attrvalue));
while ( start && (start = find_node(start, name)) ) {
s = xmlGetProp(start, attrname);
- printf(" comparing '%s' to '%s'\n", s, attrvalue);
+ d(printf(" comparing '%s' to '%s'\n", s, attrvalue));
if (s && !strcmp(s, attrvalue))
break;
start = start->next;
@@ -116,9 +118,9 @@ load_desc(xmlNodePtr node, int type, int vartype, char *varname)
desc->type = type;
desc->vartype = vartype;
desc->varname = varname?g_strdup(varname):0;
- printf(" **** node name = %s var name = %s var type = %s\n", node->name, varname, detokenise(vartype));
+ d(printf(" **** node name = %s var name = %s var type = %s\n", node->name, varname, detokenise(vartype)));
list = g_list_append(list, desc);
- printf("appending '%s'\n", node->content);
+ d(printf("appending '%s'\n", node->content));
newtype = type;
newvartype = -1;
newvarname = NULL;
@@ -129,7 +131,7 @@ load_desc(xmlNodePtr node, int type, int vartype, char *varname)
}
n = node->childs;
while (n) {
- printf("adding child '%s'\n", n->name);
+ d(printf("adding child '%s'\n", n->name));
list = g_list_concat(list, load_desc(n, newtype, newvartype, newvarname));
n = n->next;
}
@@ -157,7 +159,7 @@ filter_load_ruleset(xmlDocPtr doc)
ruletype = tokenise(xmlGetProp(ruleset, "type"));
- printf("ruleset, name = %s\n", ruleset->name);
+ d(printf("ruleset, name = %s\n", ruleset->name));
while (rule) {
@@ -166,24 +168,24 @@ filter_load_ruleset(xmlDocPtr doc)
r->type = ruletype;
r->name = xmlGetProp(rule, "name");
- printf(" rule, name = %s\n", r->name);
+ d(printf(" rule, name = %s\n", r->name));
while (n) {
type = tokenise(n->name);
- printf(" n, name = %s\n", n->name);
- printf(" ncontent = %s\n", n->content);
- printf(" childs = %p\n", n->childs);
+ d(printf(" n, name = %s\n", n->name));
+ d(printf(" ncontent = %s\n", n->content));
+ d(printf(" childs = %p\n", n->childs));
if (n->childs) {
- printf(" childs content = %s\n", n->childs->content);
+ d(printf(" childs content = %s\n", n->childs->content));
}
switch(type) {
case FILTER_XML_CODE:
r->code = xmlNodeGetContent(n);
break;
case FILTER_XML_DESC:
- printf(" ** loading description\n");
+ d(printf(" ** loading description\n"));
r->description = load_desc(n->childs, type, -1, NULL);
- printf(" ** done loading description\n");
+ d(printf(" ** done loading description\n"));
break;
default:
printf("warning, unknown token encountered\n");
@@ -203,14 +205,14 @@ filter_load_ruleset(xmlDocPtr doc)
int
filter_find_rule(struct filter_rule *a, char *name)
{
- printf("finding, is %s = %s?\n", a->name, name);
+ d(printf("finding, is %s = %s?\n", a->name, name));
return strcmp(a->name, name);
}
int
filter_find_arg(FilterArg *a, char *name)
{
- printf("finding, is %s = %s?\n", a->name, name);
+ d(printf("finding, is %s = %s?\n", a->name, name));
return strcmp(a->name, name);
}
@@ -221,19 +223,18 @@ load_optionvalue(struct filter_desc *desc, xmlNodePtr node)
int token;
int lasttoken = -2;
FilterArg *arg = NULL;
- char *name;
- printf("creating arg entry for '%s'\n", desc->varname);
+ d(printf("creating arg entry for '%s'\n", desc->varname));
switch(desc->vartype) {
case FILTER_XML_ADDRESS:
- arg = filter_arg_address_new(name);
+ arg = filter_arg_address_new(desc->varname);
break;
case FILTER_XML_FOLDER:
- arg = filter_arg_folder_new(name);
+ arg = filter_arg_folder_new(desc->varname);
break;
default:
- printf("ok, maybe we're not\n");
+ d(printf("ok, maybe we're not\n"));
/* unknown arg type, drop it */
return NULL;
}
@@ -289,14 +290,14 @@ filter_load_optionset(xmlDocPtr doc, GList *rules)
optionset = find_node(doc->root->childs, "optionset");
if (optionset == NULL) {
printf("optionset not found\n");
- return;
+ return NULL;
}
option = find_node(optionset->childs, "option");
while (option) {
o = option->childs;
op = g_malloc0(sizeof(*op));
- printf("option = %s\n", o->name);
- printf("option, type=%s\n", xmlGetProp(option, "type"));
+ d(printf("option = %s\n", o->name));
+ d(printf("option, type=%s\n", xmlGetProp(option, "type")));
op->type = tokenise(xmlGetProp(option, "type"));
while (o) {
type = tokenise(o->name);
@@ -305,7 +306,7 @@ filter_load_optionset(xmlDocPtr doc, GList *rules)
lrule = g_list_find_custom(rules, xmlGetProp(o, "rule"), (GCompareFunc) filter_find_rule);
if (lrule) {
fr = lrule->data;
- printf("found rule : %s\n", fr->name);
+ d(printf("found rule : %s\n", fr->name));
optionrule = g_malloc0(sizeof(*optionrule));
optionrule->rule = fr;
op->options = g_list_append(op->options, optionrule);
@@ -319,17 +320,20 @@ filter_load_optionset(xmlDocPtr doc, GList *rules)
/* try and see if there is a setting for this value */
or = find_node_attr(o->childs, "optionvalue", "name", desc->varname);
arg = load_optionvalue(desc, or);
- if (arg)
+ if (arg) {
optionrule->args = g_list_append(optionrule->args, arg);
+ d(printf("Adding arg %s\n", arg->name));
+ }
}
ldesc = g_list_next(ldesc);
}
} else {
+ /* FIXME: memleak */
printf("Cannot find rule: %s\n", xmlGetProp(o, "rule"));
}
break;
case FILTER_XML_DESC:
- printf("loading option descriptiong\n");
+ d(printf("loading option descriptiong\n"));
op->description = load_desc(option->childs, type, -1, NULL);
break;
}
@@ -414,8 +418,7 @@ filter_clone_optionrule_free(struct filter_optionrule *or)
GList *argl;
struct filter_optionrule *rule;
- printf("---- free optionrule\n");
- return;
+ d(printf("---- free optionrule\n"));
argl = or->args;
while (argl) {