[Evolution-hackers] Bogofilter junk plugin patch



Hello,

I've massaged my Bogofilter junk plugin into a patch for inclusion in
the Evolution source tree, attached below.
The plugin is included in the experimental list.
Index: configure.in
===================================================================
RCS file: /cvs/gnome/evolution/configure.in,v
retrieving revision 1.864
diff -u -r1.864 configure.in
--- configure.in	19 Dec 2005 11:23:08 -0000	1.864
+++ configure.in	19 Dec 2005 12:44:52 -0000
@@ -101,6 +101,7 @@
     NO_UNDEFINED='-no-undefined'
     SOEXT='.dll'
     SA_JUNK_PLUGIN=''
+    BF_JUNK_PLUGIN=''
     DL_LIB=''
     SOFTOKN3_LIB=''
     HAL_REQUIREMENT=''
@@ -109,6 +110,7 @@
     NO_UNDEFINED=''
     SOEXT='.so'
     SA_JUNK_PLUGIN=sa-junk-plugin
+    BF_JUNK_PLUGIN=bf-junk-plugin
     DL_LIB='-ldl'
     SOFTOKN3_LIB='-lsoftokn3'
     HAL_REQUIREMENT='hal'
@@ -1403,8 +1405,8 @@
 all_plugins_standard="$plugins_standard"
 
 plugins_experimental_always="backup-restore folder-unsubscribe mail-to-meeting mail-remote prefer-plain save-attachments"
-plugins_experimental="$plugins_experimental $IPOD_SYNC"
-all_plugins_experimental="$plugins_experimental_always ipod-sync"
+plugins_experimental="$plugins_experimental $IPOD_SYNC $BF_JUNK_PLUGIN"
+all_plugins_experimental="$plugins_experimental_always bf-junk-plugin ipod-sync"
 
 case x"$enable_plugins" in
 xno)
@@ -1701,6 +1703,7 @@
 plugins/groupwise-features/Makefile
 plugins/mail-account-disable/Makefile
 plugins/sa-junk-plugin/Makefile
+plugins/bf-junk-plugin/Makefile
 plugins/ipod-sync/Makefile
 plugins/publish-calendar/Makefile
 smime/Makefile
Index: po/POTFILES.in
===================================================================
RCS file: /cvs/gnome/evolution/po/POTFILES.in,v
retrieving revision 1.291
diff -u -r1.291 POTFILES.in
--- po/POTFILES.in	18 Dec 2005 12:31:19 -0000	1.291
+++ po/POTFILES.in	19 Dec 2005 12:44:56 -0000
@@ -274,6 +274,7 @@
 plugins/backup-restore/org-gnome-backup-restore.xml
 plugins/bbdb/bbdb.c
 plugins/bbdb/org-gnome-evolution-bbdb.eplug.xml
+plugins/bf-junk-plugin/org-gnome-bf-junk-plugin.eplug.xml
 plugins/calendar-file/org-gnome-calendar-file.eplug.xml
 plugins/calendar-http/calendar-http.c
 plugins/calendar-http/org-gnome-calendar-http.eplug.xml
Index: plugins/bf-junk-plugin/ChangeLog
===================================================================
RCS file: plugins/bf-junk-plugin/ChangeLog
diff -N plugins/bf-junk-plugin/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/bf-junk-plugin/ChangeLog	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,10 @@
+2005-12-18  Mikhail Zabaluev <mhz altlinux org>
+
+* Makefile.am, org-gnome-bf-junk-plugin.eplug.xml:
+Adapted for inclusion in the Evolution source tree.
+
+2005-11-22  Mikhail Zabaluev <mhz altlinux org>
+
+* README: Added reference to Spam Trainer.
+
+* README: Reflect on the fix for bug #313096 that made it to Evolution 2.5.2.
Index: plugins/bf-junk-plugin/Makefile.am
===================================================================
RCS file: plugins/bf-junk-plugin/Makefile.am
diff -N plugins/bf-junk-plugin/Makefile.am
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/bf-junk-plugin/Makefile.am	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,20 @@
+INCLUDES =						\
+	-I$(top_srcdir)					\
+	$(EVOLUTION_MAIL_CFLAGS)
+
+ EVO_PLUGIN_RULE@
+
+plugin_DATA = org-gnome-bf-junk-plugin.eplug
+plugin_LTLIBRARIES = liborg-gnome-bf-junk-plugin.la
+
+liborg_gnome_bf_junk_plugin_la_SOURCES = bf-junk-filter.c
+liborg_gnome_bf_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+BUILT_SOURCES = $(plugin_DATA) $(error_DATA)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+	org-gnome-bf-junk-plugin.eplug.xml
+
+
Index: plugins/bf-junk-plugin/README
===================================================================
RCS file: plugins/bf-junk-plugin/README
diff -N plugins/bf-junk-plugin/README
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/bf-junk-plugin/README	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,34 @@
+Bogofilter plugin for Evolution
+
+This plugin implements junk filtering for the Evolution mailer,
+provided by the bogofilter utility. Bogofilter (http://www.bogofilter.org)
+if a fast and nimble mail filter using a so-called Bayesian technique to
+classify junk and non-junk email.
+
+CAVEATS:
+
+For Evolution versions before 2.5.2, the definition file for the stock
+junk filter plugin, 'org-gnome-sa-junk-plugin.eplug', must be removed
+from the plugin directory to avoid conflict with any alternate junk plugin.
+Simply disabling the SA plugin in the configuration won't help.
+This is due to a flaw in the loading code for this hook type
+(see GNOME bug #313096).
+
+To be able to classify emails as spam, bogofilter needs to have some
+messages in its ham (non-spam) wordlist. This presents something of a
+chicken-and-egg problem for Evolution, because it can feed messages
+to the junk filter for learning as non-junk only after these messages have been
+classified as junk and moved into a junk folder. Thus, if you haven't got a
+pre-existing bogofilter database, you may need to feed it some messages known
+to be non-junk, using its command line utility:
+
+bogofilter -n < saved-ham-message
+
+Alternatively, you may use Spam Trainer, which is a GUI tool that supports
+drag-and-drop from Evolution:
+
+http://spamtrainer.sourceforge.net/
+
+Set it up to use bogofilter commands for training:
+  Ham command: bogofilter -n < %f
+  Spam command: bogofilter -s < %f
Index: plugins/bf-junk-plugin/bf-junk-filter.c
===================================================================
RCS file: plugins/bf-junk-plugin/bf-junk-filter.c
diff -N plugins/bf-junk-plugin/bf-junk-filter.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/bf-junk-plugin/bf-junk-filter.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2005 Mikhail Zabaluev <mhz altlinux org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#define G_LOG_DOMAIN "bf-junk-filter"
+
+#include <glib.h>
+#include <e-util/e-plugin.h>
+#include <mail/em-junk-hook.h>
+#include <camel/camel-data-wrapper.h>
+#include <camel/camel-stream-fs.h>
+#include <camel/camel-debug.h>
+#include <gconf/gconf-client.h>
+
+
+#ifndef BOGOFILTER_BINARY
+#define BOGOFILTER_BINARY "/usr/bin/bogofilter"
+#endif
+
+#define BOGOFILTER_ERROR 3
+
+#define EM_JUNK_BF_GCONF_DIR "/apps/evolution/mail/junk/bogofilter"
+
+
+#define d(x) (camel_debug("junk")?(x):0)
+
+
+static gchar em_junk_bf_binary[] = BOGOFILTER_BINARY;
+
+static const gchar em_junk_bf_gconf_dir[] = EM_JUNK_BF_GCONF_DIR;
+
+#define EM_JUNK_BF_GCONF_DIR_LENGTH (G_N_ELEMENTS (em_junk_bf_gconf_dir) - 1)
+
+
+static gboolean em_junk_bf_unicode = TRUE;
+
+
+static gint
+pipe_to_bogofilter (CamelMimeMessage *msg, gchar **argv)
+{
+	GPid child_pid;
+	gint bf_in;
+	CamelStream *stream;
+	GError *err = NULL;
+	gint status;
+	gint waitres;
+
+	if (camel_debug_start ("junk")) {
+		int i;
+
+		printf ("pipe_to_bogofilter ");
+		for (i = 0; argv[i]; i++)
+			printf ("%s ", argv[i]);
+		printf ("\n");
+		camel_debug_end ();
+	}
+
+	if (!g_spawn_async_with_pipes (NULL,
+	                               argv,
+	                               NULL,
+	                               G_SPAWN_DO_NOT_REAP_CHILD |
+	                                   G_SPAWN_STDOUT_TO_DEV_NULL,
+	                               NULL,
+	                               NULL,
+	                               &child_pid,
+	                               &bf_in,
+	                               NULL,
+	                               NULL,
+	                               &err))
+	{
+		g_warning ("error occurred while spawning %s: %s",
+		           argv[0],
+		           err->message);
+		return BOGOFILTER_ERROR;
+	}
+
+	stream = camel_stream_fs_new_with_fd (bf_in);
+	camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (msg), stream);
+	camel_stream_flush (stream);
+	camel_stream_close (stream);
+	camel_object_unref (stream);
+
+	waitres = waitpid (child_pid, &status, 0);
+	if (waitres < 0 && errno == EINTR) {
+		/* child process is hanging... */
+		g_warning ("wait for bogofilter child process interrupted, terminating");
+		kill (child_pid, SIGTERM);
+		sleep (1);
+		waitres = waitpid (child_pid, &status, WNOHANG);
+		if (waitres == 0) {
+			/* ...still hanging, set phasers to KILL */
+			g_warning ("bogofilter child process does not respond, killing");
+			kill (child_pid, SIGKILL);
+			sleep (1);
+			waitres = waitpid (child_pid, &status, WNOHANG);
+		}
+	}
+
+	g_spawn_close_pid (child_pid);
+
+	if (waitres >= 0 && WIFEXITED (status)) {
+		return WEXITSTATUS (status);
+	} else {
+		return BOGOFILTER_ERROR;
+	}
+}
+
+static void
+em_junk_bf_setting_notify (GConfClient *gconf,
+                           guint        cnxn_id,
+                           GConfEntry  *entry,
+                           void        *data)
+{
+	const char *key;
+	GConfValue *value;
+
+	value = gconf_entry_get_value (entry);
+	if (value == NULL) {
+		return;
+	}
+
+	key = gconf_entry_get_key (entry);
+	g_return_if_fail (key != NULL);
+
+	g_return_if_fail (!strncmp (key, em_junk_bf_gconf_dir, EM_JUNK_BF_GCONF_DIR_LENGTH));
+	key += EM_JUNK_BF_GCONF_DIR_LENGTH;
+	g_return_if_fail (*key != '/');
+	++key;
+
+	if (strcmp (key, "unicode") == 0) {
+		em_junk_bf_unicode = gconf_value_get_bool (value);
+	}
+}
+
+gboolean
+em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target)
+{
+	CamelMimeMessage *msg = target->m;
+	int rv;
+
+	gchar *argv[] = {
+		em_junk_bf_binary,
+		NULL,
+		NULL
+	};
+
+	d(fprintf (stderr, "em_junk_bf_check_junk\n"));
+
+	if (em_junk_bf_unicode) {
+		argv[1] = "--unicode=yes";
+	}
+
+	rv = pipe_to_bogofilter (msg, argv);
+
+	d(fprintf (stderr, "em_junk_bf_check_junk rv = %d\n", rv));
+
+	return (rv == 0);
+}
+
+void
+em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target)
+{
+	CamelMimeMessage *msg = target->m;
+
+	gchar *argv[] = {
+		em_junk_bf_binary,
+		"-s",
+		NULL,
+		NULL
+	};
+
+	d(fprintf (stderr, "em_junk_bf_report_junk\n"));
+
+	if (em_junk_bf_unicode) {
+		argv[2] = "--unicode=yes";
+	}
+
+	pipe_to_bogofilter (msg, argv);
+}
+
+void
+em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
+{
+	CamelMimeMessage *msg = target->m;
+
+	gchar *argv[] = {
+		em_junk_bf_binary,
+		"-n",
+		NULL,
+		NULL
+	};
+
+	d(fprintf (stderr, "em_junk_bf_report_non_junk\n"));
+
+	if (em_junk_bf_unicode) {
+		argv[2] = "--unicode=yes";
+	}
+
+	pipe_to_bogofilter (msg, argv);
+}
+
+void
+em_junk_bf_commit_reports (EPlugin *ep, EMJunkHookTarget *target)
+{
+}
+
+int
+e_plugin_lib_enable (EPluginLib *ep, int enable)
+{
+	GConfClient *gconf;
+
+	if (enable != 1) {
+		return 0;
+	}
+
+	gconf = gconf_client_get_default();
+
+	gconf_client_add_dir (gconf,
+	                      em_junk_bf_gconf_dir,
+	                      GCONF_CLIENT_PRELOAD_ONELEVEL,
+	                      NULL);
+
+	gconf_client_notify_add (gconf,
+	                         em_junk_bf_gconf_dir,
+				 em_junk_bf_setting_notify,
+				 NULL, NULL, NULL);
+
+	em_junk_bf_unicode = gconf_client_get_bool (gconf,
+		EM_JUNK_BF_GCONF_DIR "/unicode", NULL);
+
+	g_object_unref (gconf);
+
+	return 0;
+}
Index: plugins/bf-junk-plugin/org-gnome-bf-junk-plugin.eplug.xml
===================================================================
RCS file: plugins/bf-junk-plugin/org-gnome-bf-junk-plugin.eplug.xml
diff -N plugins/bf-junk-plugin/org-gnome-bf-junk-plugin.eplug.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ plugins/bf-junk-plugin/org-gnome-bf-junk-plugin.eplug.xml	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<e-plugin-list>
+	<e-plugin id="org.gnome.evolution.bf_junk_plugin" 
+		type="shlib" _name="Bogofilter junk plugin"
+		location="@PLUGINDIR@/liborg-gnome-bf-junk-plugin SOEXT@">
+		<_description>Filters junk messages using Bogofilter.</_description>
+		<author name="Mikhail Zabaluev" email="mhz altlinux org"/>
+		<hook class="org.gnome.evolution.mail.junk:1.0">
+			<group id="EMJunk">
+				<item    
+				        check_junk="em_junk_bf_check_junk" 
+				        report_junk="em_junk_bf_report_junk" 
+					report_non_junk="em_junk_bf_report_non_junk" 
+				      	commit_reports="em_junk_bf_commit_reports" />
+			</group>
+		</hook>
+	</e-plugin>
+</e-plugin-list>


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