+;;;; SpamAssassin
+;;; based mostly on the bogofilter code
+(defun spam-check-spamassassin-headers (&optional score)
+ "Check the SpamAssassin headers for the classification of this message."
+ (if score ; scoring mode
+ (let ((header (message-fetch-field spam-spamassassin-spam-status-header)))
+ (when header
+ (if (string-match "hits=\\(-?[0-9.]+\\)" header)
+ (match-string 1 header)
+ "0")))
+ ;; spam detection mode
+ (let ((header (message-fetch-field spam-spamassassin-spam-flag-header))
+ (spam-split-group (if spam-split-symbolic-return
+ 'spam
+ spam-split-group)))
+ (when header ; return nil when no header
+ (when (string-match spam-spamassassin-positive-spam-flag-header
+ header)
+ spam-split-group)))))
+
+(defun spam-check-spamassassin (&optional score)
+ "Check the SpamAssassin backend for the classification of this message."
+ (let ((article-buffer-name (buffer-name)))
+ (with-temp-buffer
+ (let ((temp-buffer-name (buffer-name)))
+ (save-excursion
+ (set-buffer article-buffer-name)
+ (apply 'call-process-region
+ (point-min) (point-max) spam-spamassassin-path
+ nil temp-buffer-name nil spam-spamassassin-arguments))
+ ;; check the return now (we're back in the temp buffer)
+ (goto-char (point-min))
+ (spam-check-spamassassin-headers score)))))
+
+;; return something sensible if the score can't be determined
+(defun spam-spamassassin-score ()
+ "Get the SpamAssassin score"
+ (interactive)
+ (save-window-excursion
+ (gnus-summary-show-article t)
+ (set-buffer gnus-article-buffer)
+ (let ((score (or (spam-check-spamassassin-headers t)
+ (spam-check-spamassassin t))))
+ (gnus-summary-show-article)
+ (message "SpamAssassin score %s" score)
+ (or score "0"))))
+
+(defun spam-spamassassin-register-with-sa-learn (articles spam
+ &optional unregister)
+ "Register articles with spamassassin's sa-learn as spam or non-spam."
+ (if articles
+ (let ((action (if unregister spam-sa-learn-unregister-switch
+ (if spam spam-sa-learn-spam-switch
+ spam-sa-learn-ham-switch)))
+ (summary-buffer-name (buffer-name)))
+ (with-temp-buffer
+ ;; group the articles into mbox format
+ (dolist (article articles)
+ (let (article-string)
+ (save-excursion
+ (set-buffer summary-buffer-name)
+ (setq article-string (spam-get-article-as-string article)))
+ (when (stringp article-string)
+ (insert "From \n") ; mbox separator (sa-learn only checks the
+ ; first five chars, so we can get away with
+ ; a bogus line))
+ (insert article-string)
+ (insert "\n"))))
+ ;; call sa-learn on all messages at the same time
+ (apply 'call-process-region
+ (point-min) (point-max)
+ spam-sa-learn-path
+ nil nil nil "--mbox"
+ (if spam-sa-learn-rebuild
+ (list action)
+ `("--no-rebuild" ,action)))))))
+
+(defun spam-spamassassin-register-spam-routine (articles &optional unregister)
+ (spam-spamassassin-register-with-sa-learn articles t unregister))
+
+(defun spam-spamassassin-register-ham-routine (articles &optional unregister)
+ (spam-spamassassin-register-with-sa-learn articles nil unregister))
+
+(defun spam-assassin-register-spam-routine (articles)
+ (spam-spamassassin-register-with-sa-learn articles t t))
+
+(defun spam-assassin-register-ham-routine (articles)
+ (spam-spamassassin-register-with-sa-learn articles nil t))
+\f