(defgroup spam nil
"Spam configuration.")
-(defcustom spam-directory "~/News/spam/"
+(defcustom spam-directory (nnheader-concat gnus-directory "spam/")
"Directory for spam whitelists and blacklists."
:type 'directory
:group 'spam)
:type 'boolean
:group 'spam)
+(defcustom spam-use-gmane-xref nil
+ "Whether the Gmane spam xref should be used by `spam-split'."
+ :type 'boolean
+ :group 'spam)
+
(defcustom spam-use-blacklist nil
"Whether the blacklist should be used by `spam-split'."
:type 'boolean
(defcustom spam-install-hooks (or
spam-use-dig
+ spam-use-gmane-xref
spam-use-blacklist
spam-use-whitelist
spam-use-whitelist-exclusive
:type '(repeat (string :tag "Group"))
:group 'spam)
+
+(defcustom spam-gmane-xref-spam-group "gmane.spam.detected"
+ "The group where spam xrefs can be found on Gmane.
+Only meaningful if you enable `spam-use-gmane-xref'."
+ :type 'string
+ :group 'spam)
+
(defcustom spam-blackhole-servers '("bl.spamcop.net" "relays.ordb.org"
"dev.null.dk" "relays.visi.com")
- "List of blackhole servers."
+ "List of blackhole servers.
+Only meaningful if you enable `spam-use-blackholes'."
:type '(repeat (string :tag "Server"))
:group 'spam)
(defcustom spam-blackhole-good-server-regex nil
- "String matching IP addresses that should not be checked in the blackholes."
+ "String matching IP addresses that should not be checked in the blackholes.
+Only meaningful if you enable `spam-use-blackholes'."
:type '(radio (const nil)
(regexp :format "%t: %v\n" :size 0))
:group 'spam)
:group 'spam)
(defcustom spam-regex-headers-spam '("^X-Spam-Flag: YES")
- "Regular expression for positive header spam matches."
+ "Regular expression for positive header spam matches.
+Only meaningful if you enable `spam-use-regex-headers'."
:type '(repeat (regexp :tag "Regular expression to match spam header"))
:group 'spam)
(defcustom spam-regex-headers-ham '("^X-Spam-Flag: NO")
- "Regular expression for positive header ham matches."
+ "Regular expression for positive header ham matches.
+Only meaningful if you enable `spam-use-regex-headers'."
:type '(repeat (regexp :tag "Regular expression to match ham header"))
:group 'spam)
(defcustom spam-regex-body-spam '()
- "Regular expression for positive body spam matches."
+ "Regular expression for positive body spam matches.
+Only meaningful if you enable `spam-use-regex-body'."
:type '(repeat (regexp :tag "Regular expression to match spam body"))
:group 'spam)
(defcustom spam-regex-body-ham '()
- "Regular expression for positive body ham matches."
+ "Regular expression for positive body ham matches.
+Only meaningful if you enable `spam-use-regex-body'."
:type '(repeat (regexp :tag "Regular expression to match ham body"))
:group 'spam)
(gnus-group-spam-exit-processor-ifile spam spam-use-ifile)
(gnus-group-spam-exit-processor-stat spam spam-use-stat)
(gnus-group-spam-exit-processor-spamoracle spam spam-use-spamoracle)
- (gnus-group-spam-exit-processor-spamassassin spam spam-use-spam-spamassassin)
+ (gnus-group-spam-exit-processor-spamassassin spam spam-use-spamassassin)
(gnus-group-ham-exit-processor-ifile ham spam-use-ifile)
(gnus-group-ham-exit-processor-bogofilter ham spam-use-bogofilter)
(gnus-group-ham-exit-processor-stat ham spam-use-stat)
(gnus-group-ham-exit-processor-whitelist ham spam-use-whitelist)
(gnus-group-ham-exit-processor-BBDB ham spam-use-BBDB)
(gnus-group-ham-exit-processor-copy ham spam-use-ham-copy)
- (gnus-group-ham-exit-processor-spamassassin ham spam-use-ham-spamassassin)
+ (gnus-group-ham-exit-processor-spamassassin ham spam-use-spamassassin)
(gnus-group-ham-exit-processor-spamoracle ham spam-use-spamoracle))
"The `spam-list-of-processors' list.
This list contains pairs associating a ham/spam exit processor
(new-articles (spam-list-articles
gnus-newsgroup-articles
classification))
- (changed-articles (gnus-set-difference old-articles new-articles)))
+ (changed-articles (gnus-set-difference new-articles old-articles)))
;; now that we have the changed articles, we go through the processors
(dolist (processor-param spam-list-of-processors)
(let ((processor (nth 0 processor-param))
(defvar spam-list-of-checks
'((spam-use-blacklist . spam-check-blacklist)
(spam-use-regex-headers . spam-check-regex-headers)
+ (spam-use-gmane-xref . spam-check-gmane-xref)
(spam-use-regex-body . spam-check-regex-body)
(spam-use-whitelist . spam-check-whitelist)
(spam-use-BBDB . spam-check-BBDB)
+ (spam-use-BBDB-exclusive . spam-check-BBDB)
(spam-use-ifile . spam-check-ifile)
(spam-use-spamoracle . spam-check-spamoracle)
(spam-use-stat . spam-check-stat)
nil
spam-whitelist-unregister-routine
nil)
+ (spam-use-ham-copy nil
+ nil
+ nil
+ nil)
(spam-use-BBDB spam-BBDB-register-routine
nil
spam-BBDB-unregister-routine
gnus-newsgroup-articles
classification)))
;; process them
- (gnus-message 5 "%s %d %s articles with classification %s, check %s"
+ (gnus-message 5 "%s %d %s articles as %s using backend %s"
(if unregister "Unregistering" "Registering")
(length articles)
(if specific-articles "specific" "")
type
cell-list))
- (gnus-error 5 (format "%s called with bad ID, type, classification, check, or group"
- "spam-log-processing-to-registry")))))
+ (gnus-error
+ 5
+ (format "%s call with bad ID, type, classification, spam-check, or group"
+ "spam-log-processing-to-registry")))))
;;; check if a ham- or spam-processor registration has been done
(defun spam-log-registered-p (id type)
(spam-process-type-valid-p type))
(cdr-safe (gnus-registry-fetch-extra id type))
(progn
- (gnus-error 5 (format "%s called with bad ID, type, classification, or check"
- "spam-log-registered-p"))
+ (gnus-error
+ 5
+ (format "%s called with bad ID, type, classification, or spam-check"
+ "spam-log-registered-p"))
nil))))
;;; check what a ham- or spam-processor registration says
nil
decision)))
+
;;; check if a ham- or spam-processor registration needs to be undone
(defun spam-log-unregistration-needed-p (id type classification check)
(when spam-log-to-registry
(setq found t))))
found)
(progn
- (gnus-error 5 (format "%s called with bad ID, type, classification, or check"
- "spam-log-unregistration-needed-p"))
+ (gnus-error
+ 5
+ (format "%s called with bad ID, type, classification, or spam-check"
+ "spam-log-unregistration-needed-p"))
nil))))
type
new-cell-list))
(progn
- (gnus-error 5 (format "%s called with bad ID, type, check, or group"
+ (gnus-error 5 (format "%s call with bad ID, type, spam-check, or group"
"spam-log-undo-registration"))
nil))))
(when (symbol-value check)
(setq nnimap-split-download-body-default t))))
+\f
+;;;; Gmane xrefs
+(defun spam-check-gmane-xref ()
+ (let ((header (or
+ (message-fetch-field "Xref")
+ (message-fetch-field "Newsgroups")))
+ (spam-split-group (if spam-split-symbolic-return
+ 'spam
+ spam-split-group)))
+ (when header ; return nil when no header
+ (when (string-match spam-gmane-xref-spam-group
+ header)
+ spam-split-group))))
+
\f
;;;; Regex body
(goto-char (point-min))
(when (re-search-forward "^X-Spam: yes;" nil t)
spam-split-group))
- (error "Error running spamoracle" status))))))))
+ (error "Error running spamoracle: %s" status))))))))
(defun spam-spamoracle-learn (articles article-is-spam-p &optional unregister)
"Run spamoracle in training mode."
`("-f" ,spam-spamoracle-database
"add" ,arg)
`("add" ,arg)))))
- (when (not (eq 0 status))
- (error "Error running spamoracle" status)))))))
+ (unless (eq 0 status)
+ (error "Error running spamoracle: %s" status)))))))
(defun spam-spamoracle-learn-ham (articles &optional unregister)
(spam-spamoracle-learn articles nil unregister))
(defun spam-spamassassin-register-ham-routine (articles &optional unregister)
(spam-spamassassin-register-with-sa-learn articles nil unregister))
-(defun spam-spamassassin-register-spam-routine (articles)
+(defun spam-spamassassin-unregister-spam-routine (articles)
(spam-spamassassin-register-with-sa-learn articles t t))
-(defun spam-spamassassin-register-ham-routine (articles)
+(defun spam-spamassassin-unregister-ham-routine (articles)
(spam-spamassassin-register-with-sa-learn articles nil t))
\f
;;;; Hooks