[evolution/eds-mailer: 2/49] MailSession reads cached filter s-expressions from disk



commit d00bbd92df7e426c5241c1ae1273be6d20d6ebba
Author: Jonathon Jongsma <jonathon quotidian org>
Date:   Mon Dec 21 14:48:10 2009 -0600

    MailSession reads cached filter s-expressions from disk
    
    This removes the dependency on any filter/* classes from the backend.  The
    backend is only concerned abou the filter expressions, not about the full tree
    of possible values, etc.  So this allows us to move all of the filter/ classes
    into the frontend.

 mail/mail-session.c |  132 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 101 insertions(+), 31 deletions(-)
---
diff --git a/mail/mail-session.c b/mail/mail-session.c
index 0341b5f..457f69e 100644
--- a/mail/mail-session.c
+++ b/mail/mail-session.c
@@ -27,6 +27,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -41,6 +42,7 @@
 
 #include <libedataserverui/e-passwords.h>
 #include <libedataserver/e-flag.h>
+#include <libedataserver/e-xml-utils.h>
 
 #include <camel/camel.h>	/* FIXME: this is where camel_init is defined, it shouldn't include everything else */
 #include <camel/camel-filter-driver.h>
@@ -510,27 +512,88 @@ session_system_beep (CamelFilterDriver *driver, gpointer user_data)
 			       driver, user_data, NULL);
 }
 
+typedef struct
+{
+	gchar *name;
+	gchar *match;
+	gchar *action;
+} FilterDefinition;
+
+static FilterDefinition *
+filter_definition_new (const xmlChar *name, const xmlChar *match, const xmlChar* action)
+{
+	FilterDefinition *def = g_slice_new0(FilterDefinition);
+	def->name = g_strdup ((gchar*) name);
+	def->match = g_strdup ((gchar*) match);
+	def->action = g_strdup ((gchar*) action);
+
+	return def;
+}
+
+static void
+filter_definition_free (FilterDefinition *filter_def)
+{
+	g_free (filter_def->name);
+	g_free (filter_def->match);
+	g_free (filter_def->action);
+	g_slice_free (FilterDefinition, filter_def);
+}
+
+/* Find all of the cached filter definitions in the given xml document and add
+ * them to the specified list.  @filters must be freed by the caller */
+static void
+append_filter_definitions (GList **filters, xmlDocPtr doc, const gchar *source)
+{
+	xmlNodePtr root, cache, child, work;
+	xmlChar *prop;
+
+	g_return_if_fail (filters != NULL && doc != NULL && source != NULL);
+
+	root = xmlDocGetRootElement (doc);
+	cache = e_xml_get_child_by_name (root, (xmlChar*) "cache");
+
+	if (!cache)
+		return;
+
+	for (child = cache->children; child; child = child->next) {
+		prop = xmlGetProp (child, (xmlChar *)"source");
+		if (prop && strcmp ((gchar*) prop, source) == 0) {
+			FilterDefinition *filter = NULL;
+			xmlChar *name, *match, *action;
+			name = xmlNodeGetContent (child);
+			work = e_xml_get_child_by_name (child, (xmlChar*) "match");
+			match = xmlNodeGetContent (work);
+			work = e_xml_get_child_by_name (child, (xmlChar*) "action");
+			action = xmlNodeGetContent (work);
+
+			filter = filter_definition_new (name, match, action);
+			*filters = g_list_append (*filters, filter);
+
+			xmlFree (name);
+			xmlFree (match);
+			xmlFree (action);
+		}
+		xmlFree (prop);
+	}
+}
+
+static void
+filter_driver_add_filter_definition (FilterDefinition *def, gpointer user_data)
+{
+	CamelFilterDriver *driver = (CamelFilterDriver*) user_data;
+	camel_filter_driver_add_rule (driver, def->name, def->match, def->action);
+}
+
+
 static CamelFilterDriver *
 main_get_filter_driver (CamelSession *session, const gchar *type, CamelException *ex)
 {
 	CamelFilterDriver *driver;
-	EFilterRule *rule = NULL;
-	const gchar *data_dir;
-	gchar *user, *system;
 	GConfClient *gconf;
-	ERuleContext *fc;
 
+	driver = camel_filter_driver_new (session);
 	gconf = mail_config_get_gconf_client ();
 
-	data_dir = mail_session_get_data_dir ();
-	user = g_build_filename (data_dir, "filters.xml", NULL);
-	system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
-	fc = (ERuleContext *) em_filter_context_new ();
-	e_rule_context_load (fc, system, user);
-	g_free (system);
-	g_free (user);
-
-	driver = camel_filter_driver_new (session);
 	camel_filter_driver_set_folder_func (driver, get_folder, NULL);
 
 	if (gconf_client_get_bool (gconf, "/apps/evolution/mail/filters/log", NULL)) {
@@ -561,33 +624,40 @@ main_get_filter_driver (CamelSession *session, const gchar *type, CamelException
 	}
 
 	if (strcmp (type, E_FILTER_SOURCE_JUNKTEST) != 0) {
-		GString *fsearch, *faction;
-
-		fsearch = g_string_new ("");
-		faction = g_string_new ("");
+		gchar *user, *system;
+		GList *filters = NULL;
+		xmlDocPtr systemdoc, userdoc;
 
 		if (!strcmp (type, E_FILTER_SOURCE_DEMAND))
 			type = E_FILTER_SOURCE_INCOMING;
 
-		/* add the user-defined rules next */
-		while ((rule = e_rule_context_next_rule (fc, rule, type))) {
-			g_string_truncate (fsearch, 0);
-			g_string_truncate (faction, 0);
+		user = g_build_filename (mail_session_get_data_dir (), "filters.xml", NULL);
+		system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
 
-			/* skip disabled rules */
-			if (!rule->enabled)
-				continue;
+		systemdoc = e_xml_parse_file (system);
+		if (systemdoc == NULL) {
+			gchar * err_msg = g_strdup_printf("Unable to load system rules '%s': %s",
+							  system, g_strerror(errno));
+			g_warning ("%s: %s", G_STRFUNC, err_msg);
+			g_free (err_msg);
+		} else {
+			append_filter_definitions (&filters, systemdoc, type);
+		}
 
-			e_filter_rule_build_code (rule, fsearch);
-			em_filter_rule_build_action ((EMFilterRule *) rule, faction);
-			camel_filter_driver_add_rule (driver, rule->name, fsearch->str, faction->str);
+		userdoc = NULL;
+		if (g_file_test (user, G_FILE_TEST_IS_REGULAR))
+			userdoc = e_xml_parse_file (user);
+		if (userdoc) {
+			append_filter_definitions (&filters, userdoc, type);
 		}
 
-		g_string_free (fsearch, TRUE);
-		g_string_free (faction, TRUE);
-	}
+		g_free (system);
+		g_free (user);
 
-	g_object_unref (fc);
+		g_list_foreach (filters, (GFunc) filter_driver_add_filter_definition, driver);
+		g_list_foreach (filters, (GFunc) filter_definition_free, NULL);
+		g_list_free (filters);
+	}
 
 	return driver;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]