(require 'dns)
(require 'message)
+;; Attempt to load BBDB macros
+(eval-when-compile
+ (condition-case nil
+ (require 'bbdb-com)
+ (file-error (defalias 'bbdb-search 'ignore))))
+
+;; autoload executable-find
+(eval-and-compile
+ ;; executable-find is not autoloaded in Emacs 20
+ (autoload 'executable-find "executable"))
+
+;; autoload ifile-spam-filter
+(eval-and-compile
+ (autoload 'ifile-spam-filter "ifile-gnus"))
+
;;; Main parameters.
(defvar spam-use-blacklist t
"True if the blacklist should be used.")
-(defvar spam-use-whitelist t
+(defvar spam-use-whitelist nil
"True if the whitelist should be used.")
(defvar spam-use-blackholes nil
;; FIXME! Turned off for now. The DNS routines are said to be flaky.
"True if blackholes should be used.")
-(defvar spam-use-bogofilter t
+(defvar spam-use-bogofilter nil
"True if bogofilter should be used.")
+(defvar spam-use-bbdb nil
+ "True if BBDB should be used.")
+
+(defvar spam-use-ifile nil
+ "True if ifile should be used.")
+
(defvar spam-split-group "spam"
"Usual group name where spam should be split.")
(gnus-define-keys gnus-summary-mode-map
"St" spam-bogofilter-score
"Sx" gnus-summary-mark-as-spam
+ "Mst" spam-bogofilter-score
+ "Msx" gnus-summary-mark-as-spam
"\M-d" gnus-summary-mark-as-spam)
;;; How to highlight a spam summary line.
\f
;;;; Spam determination.
-;; The following list contains pairs associating a parameter variable with a
-;; spam checking function. If the parameter variable is true, then the
-;; checking function is called, and its value decides what happens. Each
-;; individual check may return `nil', `t', or a mailgroup name. The value
-;; `nil' means that the check does not yield a decision, and so, that further
-;; checks are needed. The value `t' means that the message is definitely not
-;; spam, and that further spam checks should be inhibited. Otherwise, a
-;; mailgroup name is returned where the mail should go, and further checks are
-;; also inhibited. The usual mailgroup name is the value of
-;; `spam-split-group', meaning that the message is definitely a spam.
(defvar spam-list-of-checks
'((spam-use-blacklist . spam-check-blacklist)
(spam-use-whitelist . spam-check-whitelist)
(spam-use-bbdb . spam-check-bbdb)
+ (spam-use-ifile . spam-check-ifile)
(spam-use-blackholes . spam-check-blackholes)
- (spam-use-bogofilter . spam-check-bogofilter)))
+ (spam-use-bogofilter . spam-check-bogofilter))
+"The spam-list-of-checks list contains pairs associating a parameter
+variable with a spam checking function. If the parameter variable is
+true, then the checking function is called, and its value decides what
+happens. Each individual check may return `nil', `t', or a mailgroup
+name. The value `nil' means that the check does not yield a decision,
+and so, that further checks are needed. The value `t' means that the
+message is definitely not spam, and that further spam checks should be
+inhibited. Otherwise, a mailgroup name is returned where the mail
+should go, and further checks are also inhibited. The usual mailgroup
+name is the value of `spam-split-group', meaning that the message is
+definitely a spam.")
(defun spam-split ()
"Split this message into the `spam' group if it is spam.
decision)
(while (and list-of-checks (not decision))
(let ((pair (pop list-of-checks)))
- (when (eval (car pair))
- (setq decision (apply (cdr pair))))))
+ (when (symbol-value (car pair))
+ (setq decision (funcall (cdr pair))))))
(if (eq decision t)
nil
decision)))
(setq spam-whitelist-cache (spam-parse-list spam-whitelist)))
(if (spam-from-listed-p spam-whitelist-cache) nil spam-split-group))
-;;; copied from code by Alexander Kotelnikov <sacha@giotto.sj.ru>
-;; FIXME: assumes that bbdb.el is loaded
-;; FIXME: broken right now, if the "from" field can't be retrieved
-(defun spam-check-bbdb ()
- "We want messages from people who are in the BBDB not to be split to spam"
- (let ((who (message-fetch-field "from")))
- (when who
- (setq who (regexp-quote (cadr (gnus-extract-address-components who))))
- (if (bbdb-search (bbdb-records) nil nil who) nil spam-split-group))))
+;;; original idea from Alexander Kotelnikov <sacha@giotto.sj.ru>
+(condition-case nil
+ (progn
+ (require 'bbdb-com)
+ (defun spam-check-bbdb ()
+ "We want messages from people who are in the BBDB not to be split to spam"
+ (let ((who (message-fetch-field "from")))
+ (when who
+ (setq who (regexp-quote (cadr (gnus-extract-address-components who))))
+ (if (bbdb-search (bbdb-records) nil nil who) nil spam-split-group)))))
+ (file-error (setq spam-list-of-checks
+ (delete (assoc 'spam-use-bbdb spam-list-of-checks)
+ spam-list-of-checks))))
+
+;;; check the ifile backend; return nil if the mail was NOT classified as spam
+(condition-case nil
+ (progn
+ (require 'ifile-gnus)
+ ;;;
+ (defun spam-check-ifile ()
+ (let ((ifile-primary-spam-group spam-split-group))
+ (ifile-spam-filter nil))))
+ (file-error (setq spam-list-of-checks
+ (delete (assoc 'spam-use-ifile spam-list-of-checks)
+ spam-list-of-checks))))
(defun spam-check-blacklist ()
;; FIXME! Should it detect when file timestamps change?
(setq found t
cache nil)))
found))
+
\f
;;;; Training via Bogofilter. Last updated 2002-09-02.
;;; make install
;;;
;;; Here as well, you need to become super-user for the last step. Now,
-;;; initialises your word lists by doing, under your own identity:
+;;; initialize your word lists by doing, under your own identity:
;;;
;;; mkdir ~/.bogofilter
;;; touch ~/.bogofilter/badlist
Markup from spam recognisers, as well as `Xref', are to be removed from
articles before they get registered by Bogofilter.")
-;; FIXME! I do not know if Gnus has a compatibility function for
-;; `executable-find'. Here is a possible mantra for portability,
-;; until Lars decides how we really should do it.
-(unless (fboundp 'executable-find)
- (if (fboundp 'locate-file)
- (defun executable-find (command)
- (locate-file command exec-path))
- (autoload 'executable-find "executable")))
-;; End of portability mantra for `executable-find'.
-
(defvar spam-bogofilter-path (executable-find "bogofilter")
"File path of the Bogofilter executable program.
Force this variable to nil if you want to inhibit the functionality.")
(interactive)
(when (and spam-use-bogofilter spam-bogofilter-path)
(spam-bogofilter-articles nil "-v" (list (gnus-summary-article-number)))
- (save-excursion
- (set-buffer spam-output-buffer-name)
- (unless (= (point-min) (point-max))
- (display-message-or-buffer (current-buffer)
- spam-output-buffer-name)))))
+ (with-current-buffer spam-output-buffer-name
+ (unless (zerop (buffer-size))
+ (if (<= (count-lines (point-min) (point-max)) 1)
+ (progn
+ (goto-char (point-max))
+ (when (bolp)
+ (backward-char 1))
+ (message "%s" (buffer-substring (point-min) (point))))
+ (goto-char (point-min))
+ (display-buffer (current-buffer)))))))
(defun spam-bogofilter-register-routine ()
(when (and spam-use-bogofilter spam-bogofilter-path)