2007-09-28 [colin] 3.0.1cvs39
authorColin Leroy <colin@colino.net>
Fri, 28 Sep 2007 15:17:56 +0000 (15:17 +0000)
committerColin Leroy <colin@colino.net>
Fri, 28 Sep 2007 15:17:56 +0000 (15:17 +0000)
* src/plugins/spamassassin/spamassassin.c
* src/plugins/spamassassin/spamassassin.h
* src/plugins/spamassassin/spamassassin_gtk.c
Add addressbook-based whitelisting

ChangeLog
PATCHSETS
configure.ac
src/plugins/spamassassin/spamassassin.c
src/plugins/spamassassin/spamassassin.h
src/plugins/spamassassin/spamassassin_gtk.c

index d2f3453e86622506b531ab68d33d1969fb3cd1c4..6f74b4f1296e6673ac856fdb83f33d1bd7fe71e5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-09-28 [colin]     3.0.1cvs39
+
+       * src/plugins/spamassassin/spamassassin.c
+       * src/plugins/spamassassin/spamassassin.h
+       * src/plugins/spamassassin/spamassassin_gtk.c
+               Add addressbook-based whitelisting
+
 2007-09-28 [colin]     3.0.1cvs38
 
        * src/folder.c
index e0f3e6665dcc0284be2878e895752590e8e194e3..f0acd6813922f0fa0548cf79bdbeec0999c5da80 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.2.11 -r 1.1.2.12 src/prefs_folder_column.c;  cvs diff -u -r 1.10.2.20 -r 1.10.2.21 src/prefs_summary_column.c;  ) > 3.0.1cvs36.patchset
 ( cvs diff -u -r 1.52.2.51 -r 1.52.2.52 src/prefs_folder_item.c;  ) > 3.0.1cvs37.patchset
 ( cvs diff -u -r 1.213.2.163 -r 1.213.2.164 src/folder.c;  ) > 3.0.1cvs38.patchset
+( cvs diff -u -r 1.18.2.56 -r 1.18.2.57 src/plugins/spamassassin/spamassassin.c;  cvs diff -u -r 1.4.2.17 -r 1.4.2.18 src/plugins/spamassassin/spamassassin.h;  cvs diff -u -r 1.23.2.41 -r 1.23.2.42 src/plugins/spamassassin/spamassassin_gtk.c;  ) > 3.0.1cvs39.patchset
index 3e779c0ad060565c857da3ed092b6d821c68e4c6..35e81152ef54ea4afa514e78c4681d812ad7bdf5 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=0
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=38
+EXTRA_VERSION=39
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 0bf39e13adfc5a70c2bc8fce364d65fa36f362a0..b591061448e16f5bb0762f051dc77de03409ff7c 100644 (file)
@@ -49,6 +49,7 @@
 #include "log.h"
 #include "prefs_common.h"
 #include "alertpanel.h"
+#include "addr_compl.h"
 
 #ifdef HAVE_SYSEXITS_H
 #include <sysexits.h>
@@ -110,6 +111,10 @@ static PrefParam param[] = {
         NULL, NULL, NULL},
        {"mark_as_read", "TRUE", &config.mark_as_read, P_BOOL,
         NULL, NULL, NULL},
+       {"whitelist_ab", "FALSE", &config.whitelist_ab, P_BOOL,
+        NULL, NULL, NULL},
+       {"whitelist_ab_folder", N_("Any"), &config.whitelist_ab_folder, P_STRING,
+        NULL, NULL, NULL},
 
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
@@ -190,6 +195,33 @@ static MsgStatus msg_is_spam(FILE *fp)
        return is_spam ? MSG_IS_SPAM:MSG_IS_HAM;
 }
 
+static gboolean sa_found_in_addressbook(const gchar *address)
+{
+       gchar *addr = NULL;
+       gboolean found = FALSE;
+       gint num_addr = 0;
+       
+       if (!address)
+               return FALSE;
+       
+       addr = g_strdup(address);
+       extract_address(addr);
+       num_addr = complete_address(addr);
+       if (num_addr > 1) {
+               /* skip first item (this is the search string itself) */
+               int i = 1;
+               for (; i < num_addr && !found; i++) {
+                       gchar *caddr = get_complete_address(i);
+                       extract_address(caddr);
+                       if (strcasecmp(caddr, addr) == 0)
+                               found = TRUE;
+                       g_free(caddr);
+               }
+       }
+       g_free(addr);
+       return found;
+}
+
 static gboolean mail_filtering_hook(gpointer source, gpointer data)
 {
        MailFilteringData *mail_filtering_data = (MailFilteringData *) source;
@@ -214,6 +246,30 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data)
                return FALSE;
        }
 
+       if (config.whitelist_ab) {
+               gchar *ab_folderpath;
+               gboolean whitelisted = FALSE;
+
+               if (*config.whitelist_ab_folder == '\0' ||
+                       strcasecmp(config.whitelist_ab_folder, _("Any")) == 0) {
+                       /* match the whole addressbook */
+                       ab_folderpath = NULL;
+               } else {
+                       /* match the specific book/folder of the addressbook */
+                       ab_folderpath = config.whitelist_ab_folder;
+               }
+
+               start_address_completion(ab_folderpath);
+               if (msginfo->from && 
+                   sa_found_in_addressbook(msginfo->from))
+                               whitelisted = TRUE;
+               end_address_completion();
+               
+               if (whitelisted) {
+                       debug_print("message is ham (whitelisted)\n");
+                       return FALSE;
+               }
+       }
        pid = fork();
        if (pid == 0) {
                _exit(msg_is_spam(fp));
index 5a6e1f681605fa1cec5fc5eff7239fcb36bb76dc..538e4e4a374a6a3e545b5ddfd3d47da0e59b6ebf 100644 (file)
@@ -48,6 +48,8 @@ struct _SpamAssassinConfig
        guint                    timeout;
        gchar                   *username;
        gboolean                 mark_as_read;
+       gboolean                 whitelist_ab;
+       gchar                   *whitelist_ab_folder;
 };
 
 SpamAssassinConfig *spamassassin_get_config          (void);
index 7eb6716216d3ce6dc38011421340fc3acb14efe8..bf6abe2ff32ce588e9d9a0e96084b093efcfeab0 100644 (file)
@@ -39,6 +39,7 @@
 #include "spamassassin.h"
 #include "statusbar.h"
 #include "menu.h"
+#include "addressbook.h"
 
 struct SpamAssassinPage
 {
@@ -59,10 +60,19 @@ struct SpamAssassinPage
        GtkWidget *max_size;
        GtkWidget *timeout;
        GtkWidget *mark_as_read;
+       GtkWidget *whitelist_ab;
+       GtkWidget *whitelist_ab_folder_combo;
 
        SpamAssassinTransport   trans;
 };
 
+/*!
+ *\brief       Preset addressbook book/folder items
+ */
+static const gchar *whitelist_ab_folder_text [] = {
+       N_("Any")
+};
+
 struct Transport
 {
        gchar                   *name;
@@ -88,6 +98,18 @@ struct Transport transports[] = {
        { N_("Unix Socket"),    SPAMASSASSIN_TRANSPORT_UNIX,            PAGE_UNIX,    0 },
 };
 
+static void spamassassin_whitelist_ab_select_cb(GtkWidget *widget, gpointer data)
+{
+       struct SpamAssassinPage *page = (struct SpamAssassinPage *) data;
+       gchar *folderpath = NULL;
+       gboolean ret = FALSE;
+
+       folderpath = (gchar *) gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(page->whitelist_ab_folder_combo)->entry));
+       ret = addressbook_folder_selection(&folderpath);
+       if ( ret != FALSE && folderpath != NULL)
+               gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(page->whitelist_ab_folder_combo)->entry), folderpath);
+}
+
 static void foldersel_cb(GtkWidget *widget, gpointer data)
 {
        struct SpamAssassinPage *page = (struct SpamAssassinPage *) data;
@@ -188,7 +210,11 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        GtkWidget *frame_transport, *table_transport, *vbox_transport;
        GtkWidget *hbox_spamd, *hbox_max_size, *hbox_timeout;
        GtkWidget *hbox_process_emails, *hbox_save_spam;
-       GtkWidget *hbox_mark_as_read;
+       GtkWidget *hbox_mark_as_read, *hbox_whitelist;
+       GtkWidget *whitelist_ab_checkbtn;
+       GtkWidget *whitelist_ab_folder_combo;
+       GtkWidget *whitelist_ab_select_btn;
+       GList *combo_items;
 
        GtkWidget *enable_sa_checkbtn;
 
@@ -400,6 +426,39 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        gtk_widget_show(mark_as_read_checkbtn);
        gtk_box_pack_start(GTK_BOX(hbox_mark_as_read), mark_as_read_checkbtn, TRUE, TRUE, 0);
 
+       hbox_whitelist = gtk_hbox_new(FALSE, 8);
+       gtk_widget_show(hbox_whitelist);
+       gtk_box_pack_start (GTK_BOX (vbox2), hbox_whitelist, TRUE, TRUE, 0);
+
+       whitelist_ab_checkbtn = gtk_check_button_new_with_label(_("Whitelist senders found in address book/folder"));
+       gtk_widget_show(whitelist_ab_checkbtn);
+       gtk_box_pack_start(GTK_BOX(hbox_whitelist), whitelist_ab_checkbtn, FALSE, FALSE, 0);
+       gtk_tooltips_set_tip(tooltips, whitelist_ab_checkbtn,
+                       _("Messages coming from your address book contacts will be received in the normal folder even if detected as spam"), NULL);
+
+       whitelist_ab_folder_combo = gtk_combo_new();
+       gtk_widget_show(whitelist_ab_folder_combo);
+       gtk_widget_set_size_request(whitelist_ab_folder_combo, 100, -1);
+       gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(whitelist_ab_folder_combo)->entry),
+                              TRUE);
+
+       combo_items = NULL;
+       for (i = 0; i < (gint) (sizeof(whitelist_ab_folder_text) / sizeof(gchar *)); i++) {
+               combo_items = g_list_append(combo_items,
+                                           (gpointer) _(whitelist_ab_folder_text[i]));
+       }
+       gtk_combo_set_popdown_strings(GTK_COMBO(whitelist_ab_folder_combo), combo_items);
+       g_list_free(combo_items);
+
+       gtk_box_pack_start (GTK_BOX (hbox_whitelist), whitelist_ab_folder_combo, TRUE, TRUE, 0);
+
+       whitelist_ab_select_btn = gtk_button_new_with_label(_("Select ..."));
+       gtk_widget_show (whitelist_ab_select_btn);
+       gtk_box_pack_start (GTK_BOX (hbox_whitelist), whitelist_ab_select_btn, FALSE, FALSE, 0);
+       gtk_tooltips_set_tip(tooltips, whitelist_ab_select_btn,
+                       _("Click this button to select a book or folder in the address book"),
+                       NULL);
+
        SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, frame_transport);
        SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, hbox_max_size);
        SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, hbox_timeout);
@@ -408,11 +467,15 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, save_spam_folder_select);
        SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, hbox_process_emails);
        SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, mark_as_read_checkbtn);
+       SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn, whitelist_ab_folder_combo);
+       SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn, whitelist_ab_select_btn);
 
        config = spamassassin_get_config();
 
        g_signal_connect(G_OBJECT(save_spam_folder_select), "clicked",
                        G_CALLBACK(foldersel_cb), page);
+       g_signal_connect(G_OBJECT (whitelist_ab_select_btn), "clicked",
+                        G_CALLBACK(spamassassin_whitelist_ab_select_cb), page);
 
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enable_sa_checkbtn), config->enable);
        if (config->username != NULL)
@@ -421,11 +484,15 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
                gtk_entry_set_text(GTK_ENTRY(spamd_hostname_entry), config->hostname);
        if (config->socket != NULL)
                gtk_entry_set_text(GTK_ENTRY(spamd_socket_entry), config->socket);
+       if (config->whitelist_ab_folder != NULL)
+               gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(whitelist_ab_folder_combo)->entry),
+                               config->whitelist_ab_folder);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(spamd_port_spinbtn), (float) config->port);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(max_size_spinbtn), (float) config->max_size);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(timeout_spinbtn), (float) config->timeout);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(process_emails_checkbtn), config->process_emails);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_spam_checkbtn), config->receive_spam);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(whitelist_ab_checkbtn), config->whitelist_ab);
        if (config->save_folder != NULL)
                gtk_entry_set_text(GTK_ENTRY(save_spam_folder_entry), config->save_folder);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mark_as_read_checkbtn), config->mark_as_read);
@@ -445,6 +512,8 @@ static void spamassassin_create_widget_func(PrefsPage * _page,
        page->save_folder = save_spam_folder_entry;
        page->save_folder_select = save_spam_folder_select;
        page->mark_as_read = mark_as_read_checkbtn;
+       page->whitelist_ab = whitelist_ab_checkbtn;
+       page->whitelist_ab_folder_combo = whitelist_ab_folder_combo;
 
        active = 0;
        for (i = 0; i < (sizeof(transports) / sizeof(struct Transport)); i++) {
@@ -530,6 +599,12 @@ static void spamassassin_save_func(PrefsPage *_page)
        /* mark_as_read */
        config->mark_as_read = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->mark_as_read));
 
+       /* whitelist_ab */
+       config->whitelist_ab = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->whitelist_ab));
+       g_free(config->whitelist_ab_folder);
+       config->whitelist_ab_folder = gtk_editable_get_chars(
+                               GTK_EDITABLE(GTK_COMBO(page->whitelist_ab_folder_combo)->entry), 0, -1);
+
        if (config->process_emails) {
                spamassassin_register_hook();
        } else {