From 8dfd4278a78e7d6ae30f92d50ee46029a5fbd106 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 12 Jul 2011 07:06:12 -0400 Subject: 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. --- plugins/bogo-junk-plugin/Makefile.am | 67 ---- plugins/bogo-junk-plugin/README | 35 -- plugins/bogo-junk-plugin/bf-junk-filter.c | 420 --------------------- .../bogo-junk-plugin/bogo-junk-plugin.schemas.in | 18 - .../org-gnome-bogo-junk-plugin.eplug.xml | 26 -- 5 files changed, 566 deletions(-) delete mode 100644 plugins/bogo-junk-plugin/Makefile.am delete mode 100644 plugins/bogo-junk-plugin/README delete mode 100644 plugins/bogo-junk-plugin/bf-junk-filter.c delete mode 100644 plugins/bogo-junk-plugin/bogo-junk-plugin.schemas.in delete mode 100644 plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml (limited to 'plugins/bogo-junk-plugin') 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 - * - * - * Authors: - * Mikhail Zabaluev - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * Copyright 2005 Mikhail Zabaluev - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#define G_LOG_DOMAIN "bf-junk-filter" - -#ifndef G_OS_WIN32 -# include -#else -# include -#endif - -#include -#include -#include -#include "mail/em-config.h" -#include -#include -#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 @@ - - - - /schemas/apps/evolution/mail/junk/bogofilter/unicode - /apps/evolution/mail/junk/bogofilter/unicode - bf-eplugin - bool - true - - Convert mail messages to Unicode - - Convert message text to Unicode UTF-8 to unify spam/ham tokens - coming from different character sets. - - - - - 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 @@ - - - - <_description>Filter junk messages using Bogofilter. - - - - - - - - - - - - - - -- cgit v1.2.3