diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2011-07-12 19:06:12 +0800 |
---|---|---|
committer | Rodrigo Moya <rodrigo@gnome-db.org> | 2011-09-14 20:08:36 +0800 |
commit | c238fbfd1525aa282673abdc435a7f9e4a7f7f3e (patch) | |
tree | 4032b73901eebd34a00100cd458cfa13cd472c7b /plugins/bogo-junk-plugin | |
parent | cabf0e563627d5765a459da23b79bdb09b2c1284 (diff) | |
download | gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.tar gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.tar.gz gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.tar.bz2 gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.tar.lz gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.tar.xz gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.tar.zst gsoc2013-evolution-c238fbfd1525aa282673abdc435a7f9e4a7f7f3e.zip |
Convert junk filtering EPlugins to EExtensions.
We now have a proper junk mail filtering API. All junk filtering
extensions must subclass EMailJunkFilter for user preferences and
availability testing, and implement the CamelJunkFilter interface
for the actual junk filtering and learning operations.
The bogofilter module should be feature-equivalent to its former
EPlugin. The spamassassin module is far more complex. It's nearly
feature-equivalent to its former EPlugin, but I ditched the spamd
respawning code since it seemed unnecessary for a mail client to
have to deal with. If there's a huge outcry from users about it
I'll reluctantly put it back, but I don't expect one.
This gets us a step closer to killing off EConfig, and eventually
the EPlugin framework itself.
Diffstat (limited to 'plugins/bogo-junk-plugin')
-rw-r--r-- | plugins/bogo-junk-plugin/Makefile.am | 67 | ||||
-rw-r--r-- | plugins/bogo-junk-plugin/README | 35 | ||||
-rw-r--r-- | plugins/bogo-junk-plugin/bf-junk-filter.c | 420 | ||||
-rw-r--r-- | plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in | 18 | ||||
-rw-r--r-- | plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml | 26 |
5 files changed, 0 insertions, 566 deletions
diff --git a/plugins/bogo-junk-plugin/Makefile.am b/plugins/bogo-junk-plugin/Makefile.am deleted file mode 100644 index c4ee4a65ac..0000000000 --- a/plugins/bogo-junk-plugin/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-bogo-junk-plugin.eplug - -plugin_LTLIBRARIES = liborg-gnome-bogo-junk-plugin.la - -liborg_gnome_bogo_junk_plugin_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -DWELCOME_MESSAGE=\""$(privdatadir)/default/C/mail/local/Inbox"\" \ - $(GNOME_PLATFORM_CFLAGS) \ - $(EVOLUTION_MAIL_CFLAGS) - -liborg_gnome_bogo_junk_plugin_la_SOURCES = bf-junk-filter.c - -liborg_gnome_bogo_junk_plugin_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_bogo_junk_plugin_la_LIBADD = \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/shell/libeshell.la \ - $(EVOLUTION_MAIL_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -schemadir = $(GCONF_SCHEMA_FILE_DIR) -schema_in_files = bogo-junk-plugin.schemas.in -schema_DATA = $(schema_in_files:.schemas.in=.schemas) - -@INTLTOOL_SCHEMAS_RULE@ - -if GCONF_SCHEMAS_INSTALL - -if OS_WIN32 -install-data-local: - if test -z "$(DESTDIR)" ; then \ - for p in $(schema_DATA) ; do \ - (echo set GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE); \ - echo $(GCONFTOOL) --makefile-install-rule $$p) >_temp.bat; \ - cmd /c _temp.bat; \ - rm _temp.bat; \ - done \ - fi -else -install-data-local: - if test -z "$(DESTDIR)" ; then \ - for p in $(schema_DATA) ; do \ - GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) \ - $(GCONFTOOL) --makefile-install-rule $$p; \ - done \ - fi -endif - -endif - - -BUILT_SOURCES = $(plugin_DATA) $(error_DATA) - -CLEANFILES = $(BUILT_SOURCES) - -DISTCLEANFILES = $(schema_DATA) - -EXTRA_DIST = \ - org-gnome-bogo-junk-plugin.eplug.xml \ - $(schema_in_files) - - --include $(top_srcdir)/git.mk diff --git a/plugins/bogo-junk-plugin/README b/plugins/bogo-junk-plugin/README deleted file mode 100644 index a14bcf6dda..0000000000 --- a/plugins/bogo-junk-plugin/README +++ /dev/null @@ -1,35 +0,0 @@ -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 (GNOME bug #322105). -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 diff --git a/plugins/bogo-junk-plugin/bf-junk-filter.c b/plugins/bogo-junk-plugin/bf-junk-filter.c deleted file mode 100644 index 0d6726fd03..0000000000 --- a/plugins/bogo-junk-plugin/bf-junk-filter.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Mikhail Zabaluev <mikhail.zabaluev@gmail.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright 2005 Mikhail Zabaluev <mikhail.zabaluev@gmail.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <signal.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -#define G_LOG_DOMAIN "bf-junk-filter" - -#ifndef G_OS_WIN32 -# include <sys/wait.h> -#else -# include <windows.h> -#endif - -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <e-util/e-plugin.h> -#include "mail/em-config.h" -#include <mail/em-junk.h> -#include <gconf/gconf-client.h> -#include "shell/e-shell.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 gboolean is_installed = FALSE; - -static gchar em_junk_bf_binary[] = BOGOFILTER_BINARY; - -static const gchar em_junk_bf_gconf_dir[] = EM_JUNK_BF_GCONF_DIR; -GtkWidget * org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data); - -/* plugin fonction prototypes */ -gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target); -gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target); -void em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target); - -static gint -pipe_to_bogofilter (CamelMimeMessage *msg, - const gchar **argv, - GCancellable *cancellable, - GError **error); - -/* eplugin stuff */ -gint e_plugin_lib_enable (EPlugin *ep, gint enable); - -#define EM_JUNK_BF_GCONF_DIR_LENGTH (G_N_ELEMENTS (em_junk_bf_gconf_dir) - 1) - -static gboolean em_junk_bf_unicode = TRUE; - -static void -init_db (void) -{ - CamelStream *stream = camel_stream_fs_new_with_name (WELCOME_MESSAGE, O_RDONLY, 0, NULL); - CamelMimeParser *parser = camel_mime_parser_new (); - CamelMimeMessage *msg = camel_mime_message_new (); - const gchar *argv[] = { - em_junk_bf_binary, - "-n", - NULL, - NULL - }; - - camel_mime_parser_init_with_stream (parser, stream, NULL); - camel_mime_parser_scan_from (parser, FALSE); - g_object_unref (stream); - - camel_mime_part_construct_from_parser_sync ( - (CamelMimePart *) msg, parser, NULL, NULL); - g_object_unref (parser); - - d(fprintf (stderr, "Initing the bogofilter DB with Welcome message\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, NULL); - g_object_unref (msg); - -} - -static gint -pipe_to_bogofilter (CamelMimeMessage *msg, - const gchar **argv, - GCancellable *cancellable, - GError **error) -{ - GPid child_pid; - gint bf_in; - CamelStream *stream; - GError *err = NULL; - gint status; - gint waitres; - gint res; - static gboolean only_once = FALSE; - -retry: - if (camel_debug_start ("junk")) { - gint 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, - (gchar **) 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); - - if (g_error_matches (err, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT)) { - if (is_installed) - g_set_error (error, EM_JUNK_ERROR, err->code, _("Bogofilter is not available. Please install it first.")); - is_installed = FALSE; - } else { - /* For Translators: The first %s stands for the executable full path with a file name, the second is the error message itself. */ - g_set_error (error, EM_JUNK_ERROR, err->code, _("Error occurred while spawning %s: %s."), argv[0], err->message); - } - - g_error_free (err); - - return BOGOFILTER_ERROR; - } - - stream = camel_stream_fs_new_with_fd (bf_in); - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (msg), stream, cancellable, NULL); - camel_stream_flush (stream, cancellable, NULL); - camel_stream_close (stream, cancellable, NULL); - g_object_unref (stream); - -#ifndef G_OS_WIN32 - 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_set_error (error, EM_JUNK_ERROR, -2, _("Bogofilter child process does not respond, killing...")); - } else - g_set_error (error, EM_JUNK_ERROR, -3, _("Wait for Bogofilter child process interrupted, terminating...")); - } - - if (waitres >= 0 && WIFEXITED (status)) { - res = WEXITSTATUS (status); - } else { - res = BOGOFILTER_ERROR; - } -#else - WaitForSingleObject (child_pid, INFINITE); - GetExitCodeProcess (child_pid, &res); -#endif - - g_spawn_close_pid (child_pid); - - if (res < 0 || res > 2) { - if (!only_once) { - /* Create wordlist.db */ - only_once = TRUE; - init_db (); - - goto retry; - } - g_set_error (error, EM_JUNK_ERROR, res, _("Pipe to Bogofilter failed, error code: %d."), res); - - } - - return res; -} - -static void -em_junk_bf_setting_notify (GConfClient *gconf, - guint cnxn_id, - GConfEntry *entry, - void *data) -{ - const gchar *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, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - gint rv; - - const gchar *argv[] = { - em_junk_bf_binary, - NULL, - NULL - }; - - if (!is_installed) - return FALSE; - - d(fprintf (stderr, "em_junk_bf_check_junk\n")); - - if (em_junk_bf_unicode) { - argv[1] = "--unicode=yes"; - } - - rv = pipe_to_bogofilter (msg, argv, NULL, &target->error); - - d(fprintf (stderr, "em_junk_bf_check_junk rv = %d\n", rv)); - - return (rv == 0); -} - -void -em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - - const gchar *argv[] = { - em_junk_bf_binary, - "-s", - NULL, - NULL - }; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_bf_report_junk\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, &target->error); -} - -void -em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target) -{ - CamelMimeMessage *msg = target->m; - - const gchar *argv[] = { - em_junk_bf_binary, - "-n", - NULL, - NULL - }; - - if (!is_installed) - return; - - d(fprintf (stderr, "em_junk_bf_report_non_junk\n")); - - if (em_junk_bf_unicode) { - argv[2] = "--unicode=yes"; - } - - pipe_to_bogofilter (msg, argv, NULL, &target->error); -} - -void -em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target) -{ - if (!is_installed) - return; -} - -gpointer -em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target) -{ - gpointer res = g_file_test (em_junk_bf_binary, G_FILE_TEST_EXISTS) ? (gpointer) "1" : NULL; - - if (res != NULL) - is_installed = TRUE; - - return res; -} - -gint -e_plugin_lib_enable (EPlugin *ep, gint enable) -{ - static gboolean first = TRUE; - GConfClient *gconf; - - is_installed = enable != 0; - - if (!first) - return 0; - - first = FALSE; - 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; -} - -static void -convert_unicode_cb (GtkWidget *widget, gpointer data) -{ - - gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - GConfClient *gconf = gconf_client_get_default (); - - gconf_client_set_bool (gconf, data, active, NULL); - - g_object_unref (gconf); -} - -GtkWidget * -org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data) -{ - EShell *shell; - GtkWidget *check; - guint n_rows; - - g_object_get (data->parent, "n-rows", &n_rows, NULL); - - if (data->old) - return data->old; - - check = gtk_check_button_new_with_mnemonic (_("Convert message text to _Unicode")); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), em_junk_bf_unicode); - g_signal_connect (GTK_TOGGLE_BUTTON (check), "toggled", G_CALLBACK (convert_unicode_cb), (gpointer) "/apps/evolution/mail/junk/bogofilter/unicode"); - gtk_table_attach ( - GTK_TABLE (data->parent), check, - 0, 1, n_rows, n_rows+1, 0, 0, 0, 0); - - shell = e_shell_get_default (); - if (e_shell_get_express_mode (shell)) - gtk_widget_hide (check); - else - gtk_widget_show (check); - - return check; -} - diff --git a/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in b/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in deleted file mode 100644 index d4bfbb5b70..0000000000 --- a/plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in +++ /dev/null @@ -1,18 +0,0 @@ -<gconfschemafile> - <schemalist> - <schema> - <key>/schemas/apps/evolution/mail/junk/bogofilter/unicode</key> - <applyto>/apps/evolution/mail/junk/bogofilter/unicode</applyto> - <owner>bf-eplugin</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Convert mail messages to Unicode</short> - <long> - Convert message text to Unicode UTF-8 to unify spam/ham tokens - coming from different character sets. - </long> - </locale> - </schema> - </schemalist> -</gconfschemafile> diff --git a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml deleted file mode 100644 index 1317b988d9..0000000000 --- a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<e-plugin-list> - <e-plugin type="shlib" - location="@PLUGINDIR@/liborg-gnome-bogo-junk-plugin.so" - id="org.gnome.evolution.bogo.bf_junk_plugin" - _name="Bogofilter Junk Filter"> - <_description>Filter junk messages using Bogofilter.</_description> - <author name="Mikhail Zabaluev" email="mhz@altlinux.org"/> - <hook class="org.gnome.evolution.mail.junk:1.0"> - <interface name="Bogofilter" - report_non_junk="em_junk_bf_report_non_junk" - report_junk="em_junk_bf_report_junk" - check_junk="em_junk_bf_check_junk" - commit_reports="em_junk_bf_commit_reports" - validate_binary="em_junk_bf_validate_binary"/> - </hook> - <!-- hook into the 'mail properties' menu --> - <hook class="org.gnome.evolution.mail.config:1.0"> - <group target="prefs" id="org.gnome.evolution.mail.prefs"> - <item type="section_table" path="40.junk/30.options" _label="Bogofilter Options"/> - <item type="item_table" path="40.junk/40.options" factory="org_gnome_bogo_convert_unicode"/> - </group> - </hook> - - </e-plugin> -</e-plugin-list> |