* elmo-split.el (elmo-split-spam-p): New function.
* elmo-spam.el: New file.
* elsp-bogofilter.el: Ditto.
* WL-ELS (WL-MODULES): Added wl-spam.
(ELMO-MODULES): Added elmo-spam and elsp-bogofilter.
+2003-10-20 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+
+ * WL-ELS (WL-MODULES): Added wl-spam.
+ (ELMO-MODULES): Added elmo-spam and elsp-bogofilter.
+
2003-09-22 Yuuichi Teranishi <teranisi@gohome.org>
* WL-ELS (ELMO-MODULES): Added modb-entity (again).
wl-vars wl-draft wl-util wl-version wl-address wl-addrmgr
wl-highlight wl-demo wl-refile wl-thread
wl-fldmgr wl-expire wl-template wl-score wl-acap wl-news
+ wl-spam
))
(defconst ELMO-MODULES '(
elmo-archive elmo-pipe elmo-cache
elmo-internal elmo-flag elmo-sendlog
elmo-dop elmo-nmz elmo-split
+ elmo-spam elsp-bogofilter
modb modb-entity modb-legacy modb-standard
))
+2003-10-20 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+
+ * elmo-split.el (elmo-split-spam-p): New function.
+
+ * elmo-spam.el: New file.
+
+ * elsp-bogofilter.el: Ditto.
+
2003-10-15 Yuuichi Teranishi <teranisi@gohome.org>
* elmo.el (elmo-folder-next-message-number): New API.
--- /dev/null
+;;; elmo-spam.el --- Spam filtering interface to processor.
+
+;; Copyright (C) 2003 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Copyright (C) 2003 Yuuichi Teranishi <teranisi@gohome.org>
+
+;; Author: Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Keywords: mail, net news, spam
+
+;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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 General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+
+;;; Commentary:
+;;
+
+;;; Code:
+;;
+
+(eval-when-compile (require 'cl))
+
+(require 'luna)
+(require 'elmo-util)
+(require 'elmo)
+
+(defgroup elmo-spam nil
+ "Spam configuration for wanderlust."
+ :group 'elmo)
+
+(defcustom elmo-spam-scheme nil
+ "*Scheme of spam processor implementation. "
+ :type '(choice (const :tag "none" nil)
+ (const :tag "Bogofilter" bogofilter))
+ :group 'elmo-spam)
+
+(eval-and-compile
+ (luna-define-class elsp-generic ()))
+
+;; required method
+(luna-define-generic elmo-spam-buffer-spam-p (processor buffer)
+ "Return non-nil if contents of BUFFER is spam.
+PROCESSOR is spam processor structure.")
+
+(luna-define-generic elmo-spam-register-spam-buffer (processor buffer)
+ "Register contents of BUFFER as spam.
+PROCESSOR is spam processor structure.")
+
+(luna-define-generic elmo-spam-register-good-buffer (processor buffer)
+ "Register contents of BUFFER as non spam.
+PROCESSOR is spam processor structure.")
+
+;; optional method
+(luna-define-generic elmo-spam-message-spam-p (processor folder number)
+ "Return non-nil if the message in the FOLDER with NUMBER is spam.
+PROCESSOR is spam processor structure.")
+
+(luna-define-generic elmo-spam-list-spam-messages (processor
+ folder &optional numbers)
+ "Return a list of message numbers which is gussed spam.
+PROCESSOR is spam processor structure.
+FOLDER is the ELMO folder structure.
+If optional argument NUMBERS is specified and is a list of message numbers,
+messages are searched from the list.")
+
+(luna-define-generic elmo-spam-register-spam-messages (processor
+ folder &optional numbers)
+ "Register contents of messages as spam.
+PROCESSOR is spam processor structure.
+FOLDER is the ELMO folder structure.
+If optional argument NUMBERS is specified and is a list of message numbers,
+messages are searched from the list.")
+
+(luna-define-generic elmo-spam-register-good-messages (processor
+ folder &optional numbers)
+ "Register contents of messages as non spam.
+PROCESSOR is spam processor structure.
+FOLDER is the ELMO folder structure.
+If optional argument NUMBERS is specified and is a list of message numbers,
+messages are searched from the list.")
+
+;; for internal use
+(defun elmo-spam-message-fetch (folder number)
+ (let (elmo-message-fetch-threshold)
+ (elmo-message-fetch
+ folder number
+ (elmo-find-fetch-strategy folder
+ (elmo-message-entity folder number))
+ nil (current-buffer) 'unread)))
+
+;; generic implement
+(luna-define-method elmo-spam-message-spam-p ((processor elsp-generic)
+ folder number)
+ (with-temp-buffer
+ (elmo-spam-message-fetch folder number)
+ (elmo-spam-buffer-spam-p processor (current-buffer))))
+
+(luna-define-method elmo-spam-list-spam-messages ((processor elsp-generic)
+ folder &optional numbers)
+ (let ((numbers (or numbers (elmo-folder-list-messages folder t t)))
+ spam-list)
+ (dolist (number numbers)
+ (when (elmo-spam-message-spam-p processor folder number)
+ (setq spam-list (cons number spam-list)))
+ (elmo-progress-notify 'elmo-spam-check-spam))
+ (nreverse spam-list)))
+
+(luna-define-method elmo-spam-register-spam-messages ((processor elsp-generic)
+ folder &optional numbers)
+ (let ((numbers (or numbers (elmo-folder-list-messages folder t t))))
+ (with-temp-buffer
+ (buffer-disable-undo (current-buffer))
+ (dolist (number numbers)
+ (erase-buffer)
+ (elmo-spam-message-fetch folder number)
+ (elmo-spam-register-spam-buffer processor (current-buffer))
+ (elmo-progress-notify 'elmo-spam-register)))))
+
+(luna-define-method elmo-spam-register-good-messages ((processor elsp-generic)
+ folder &optional numbers)
+ (let ((numbers (or numbers (elmo-folder-list-messages folder t t))))
+ (with-temp-buffer
+ (buffer-disable-undo (current-buffer))
+ (dolist (number numbers)
+ (erase-buffer)
+ (elmo-spam-message-fetch folder number)
+ (elmo-spam-register-good-buffer processor (current-buffer))
+ (elmo-progress-notify 'elmo-spam-register)))))
+
+(provide 'elsp-generic)
+
+(defvar elmo-spam-processor-internal nil)
+
+(defun elmo-spam-processor ()
+ (or elmo-spam-processor-internal
+ (let* ((scheme (or elmo-spam-scheme 'generic))
+ (class (intern (format "elsp-%s" scheme))))
+ (require class)
+ (setq elmo-spam-processor-internal
+ (luna-make-entity class)))))
+
+(require 'product)
+(product-provide (provide 'elmo-spam) (require 'elmo-version))
+
+;;; elmo-sapm.el ends here
;; according to the definition of `elmo-split-rule'.
;;
+;;; Code:
(require 'elmo)
-;;; Code:
+(eval-when-compile
+ ;; Avoid compile warnings
+ (defun-maybe elmo-spam-processor)
+ (defun-maybe elmo-spam-buffer-spam-p (processor buffer)))
+
(defcustom elmo-split-rule nil
"Split rule for the command `elmo-split'.
The format of this variable is a list of RULEs which has form like:
`or' ... True if one of the argument returns true.
`and' ... True if all of the arguments return true.
-4. A symbol.
+4. Functions which accept not argument.
+
+`spam-p' ... True if contents of the message is guessed as spam.
+
+5. A symbol.
When a symbol is specified, it is evaluated.
(symbol-name field)))))
(equal field-value value))))
+(defun elmo-split-spam-p (buffer)
+ (require 'elmo-spam)
+ (elmo-spam-buffer-spam-p (elmo-spam-processor) buffer))
+
(defun elmo-split-match (buffer field value)
(with-current-buffer buffer
(let ((field-value (and elmo-split-message-entity
--- /dev/null
+;;; elsp-bogofilter.el --- Bogofilter support for elmo-spam.
+
+;; Copyright (C) 2003 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Copyright (C) 2003 Yuuichi Teranishi <teranisi@gohome.org>
+
+;; Author: Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Keywords: mail, net news, spam
+
+;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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 General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+
+;;; Commentary:
+;;
+
+;;; Code:
+;;
+(require 'elmo-spam)
+
+(require 'luna)
+(require 'path-util)
+
+(defgroup elmo-spam-bogofilter nil
+ "Spam bogofilter configuration."
+ :group 'elmo-spam)
+
+(defcustom elmo-spam-bogofilter-program (exec-installed-p "bogofilter")
+ "File path of the Bogofilter executable program."
+ :type '(choice (file :tag "Location of bogofilter")
+ (const :tag "Bogofilter is not installed"))
+ :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-header "X-Bogosity"
+ "The header that Bogofilter inserts in messages."
+ :type 'string
+ :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-spam-switch "-s"
+ "The switch that Bogofilter uses to register spam messages."
+ :type 'string
+ :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-good-switch "-n"
+ "The switch that Bogofilter uses to register non spam messages."
+ :type 'string
+ :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-bogosity-positive-spam-header "^\\(Yes\\|Spam\\)"
+ "The regexp on `elmo-spam-bogofilter' for positive spam identification."
+ :type 'regexp
+ :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-database-directory nil
+ "Directory path of the Bogofilter databases."
+ :type '(choice (directory :tag "Location of the Bogofilter database directory")
+ (const :tag "Use the default"))
+ :group 'elmo-spam-bogofilter)
+
+(eval-and-compile
+ (luna-define-class elsp-bogofilter (elsp-generic)))
+
+(luna-define-method elmo-spam-buffer-spam-p ((processor elsp-bogofilter)
+ buffer)
+ (let ((args `("-v" "-2"
+ ,@(if elmo-spam-bogofilter-database-directory
+ (list "-d" elmo-spam-bogofilter-database-directory)))))
+ (with-current-buffer buffer
+ (= 0 (apply #'call-process-region
+ (point-min) (point-max)
+ elmo-spam-bogofilter-program
+ nil nil nil args)))))
+
+(defsubst elmo-spam-bogofilter-register-buffer (buffer spam)
+ (let ((args `("-v"
+ ,(if spam
+ elmo-spam-bogofilter-spam-switch
+ elmo-spam-bogofilter-good-switch)
+ ,@(if elmo-spam-bogofilter-database-directory
+ (list "-d" elmo-spam-bogofilter-database-directory)))))
+ (with-current-buffer buffer
+ (apply #'call-process-region
+ (point-min) (point-max)
+ elmo-spam-bogofilter-program
+ nil nil nil args))))
+
+(luna-define-method elmo-spam-register-spam-buffer ((processor elsp-bogofilter)
+ buffer)
+ (elmo-spam-bogofilter-register-buffer buffer t))
+
+(luna-define-method elmo-spam-register-good-buffer ((processor elsp-bogofilter)
+ buffer)
+ (elmo-spam-bogofilter-register-buffer buffer nil))
+
+(require 'product)
+(product-provide (provide 'elsp-bogofilter) (require 'elmo-version))
+
+;;; elsp-bogofilter.el ends here
;; \e$B$^$;$s!#\e(Bnil \e$B$G$9$Y$F$N%a%C%;!<%8$,BP>]$K$J$j$^$9!#\e(B
;(setq wl-summary-auto-refile-skip-marks nil)
+;;; [[ spam \e$BMQ$N@_Dj\e(B ]]
+
+;; \e$B%P%C%/%(%s%I$K\e(B bogofilter \e$B$r;H$&;v$r@_Dj\e(B
+;(setq elmo-spam-scheme 'bogofilter)
+
+;(require 'wl-spam)
+
+;; \e$B%5%^%j%P%C%U%!$G\e(B `o' (wl-summary-refile) \e$B$7$?;~\e(B, *\e$B:G=i\e(B*\e$B$K\e(B spam \e$B$+$I\e(B
+;; \e$B$&$+$rH=Dj$9$kMM$K$9$k\e(B
+;(unless (memq 'wl-refile-guess-by-spam wl-refile-guess-functions)
+; (setq wl-refile-guess-functions
+; (cons #'wl-refile-guess-by-spam
+; wl-refile-guess-functions)))
+
+;; \e$B%5%^%j%P%C%U%!$G\e(B `C-o' (wl-summary-auto-refile) \e$B$7$?;~\e(B, *\e$B:G=i\e(B*\e$B$K\e(B
+;; spam \e$B$+$I$&$+$rH=Dj$9$kMM$K$9$k\e(B
+;(unless (memq 'wl-refile-guess-by-spam wl-auto-refile-guess-functions)
+; (setq wl-auto-refile-guess-functions
+; (cons #'wl-refile-guess-by-spam
+; wl-auto-refile-guess-functions)))
+
+;; refile-rule \e$B$rM%@h$7$?$$>l9g\e(B (spamfilter-wl.el \e$B$d\e(B bogofilter-wl.el
+;; \e$B$HF1$8@_Dj\e(B) \e$B$O\e(B, \e$B$3$C$A$N@_Dj$rM-8z$K$9$k\e(B
+;(unless (memq 'wl-refile-guess-by-spam wl-auto-refile-guess-functions)
+; (setq wl-auto-refile-guess-functions
+; (append wl-auto-refile-guess-functions
+; '(wl-refile-guess-by-spam))))
+
+;; wl-spam-auto-check-policy-alist \e$B$N@_Dj$K=>$C$F3F%5%^%j$K0\F0$7$?;~\e(B
+;; \e$B$K\e(B spam \e$B$+$I$&$+%A%'%C%/$9$k\e(B
+;(add-hook 'wl-summary-prepared-pre-hook #'wl-summary-auto-check-spam)
+
+;; +inbox \e$B$KF~$C$?;~\e(B, spam \e$B$HH=Dj$5$l$?%a%C%;!<%8$K%j%U%!%$%k%^!<%/$r\e(B
+;; \e$BIU$1$k>l9g$N@_Dj\e(B
+;(setq wl-spam-auto-check-policy-alist '(("\\+inbox" . refile)))
+
+;; refile \e$B$N<B9T;~$K3X=,$5$;$k0Y$N@_Dj\e(B
+;; \e$B0J2<$N@_Dj$r$7$?$+$i$H8@$C$F>o$K3X=,$9$kLu$G$O$"$j$^$;$s\e(B. \e$B>\$7$/$O\e(B,
+;; wl-spam.el \e$B$N\e(B wl-spam-undecided-folder-regexp-list \e$B$H\e(B
+;; wl-spam-ignored-folder-regexp-list \e$B$N\e(B docstring \e$B$r;2>H$7$F2<$5$$\e(B.
+;(let ((actions wl-summary-mark-action-list)
+; action)
+; (while actions
+; (setq action (car actions)
+; actions (cdr actions))
+; (when (eq (wl-summary-action-symbol action) 'refile)
+; (setf (nth 4 action) 'wl-summary-exec-action-refile-with-register)
+; (setq actions nil))))
+
;;; dot.wl ends here
2003-10-20 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+ * wl-spam.el: New file.
+
+2003-10-20 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+
* wl-refile.el (wl-refile-guess): Added second argument `functions'.
* wl-action.el (wl-auto-refile-guess-functions): New variable.
--- /dev/null
+;;; wl-spam.el --- Spam filtering interface for Wanderlust.
+
+;; Copyright (C) 2003 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Copyright (C) 2003 Yuuichi Teranishi <teranisi@gohome.org>
+
+;; Author: Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Keywords: mail, net news, spam
+
+;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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 General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+
+;;; Commentary:
+;;
+
+;;; Code:
+;;
+
+(eval-when-compile (require 'cl))
+
+(require 'elmo-spam)
+(require 'wl-summary)
+(require 'wl-action)
+
+(defgroup wl-spam nil
+ "Spam configuration for wanderlust."
+ :group 'wl)
+
+(defcustom wl-spam-folder-name "+spam"
+ "*Spam folder."
+ :type 'string
+ :group 'wl-spam)
+
+(defcustom wl-spam-undecided-folder-regexp-list '("inbox")
+ "*List of folder regexp which is contained undecided domain."
+ :type '(repeat (regexp :tag "Folder Regexp"))
+ :group 'wl-spam)
+
+(defcustom wl-spam-ignored-folder-regexp-list
+ (list (regexp-opt (list wl-draft-folder
+ wl-trash-folder
+ wl-queue-folder)))
+ "*List of folder regexp which is contained ignored domain."
+ :type '(repeat (regexp :tag "Folder Regexp"))
+ :group 'wl-spam)
+
+(defcustom wl-spam-auto-check-policy-alist '(("inbox" . mark))
+ "*Alist of Folder regexp which check spam automatically and policy."
+ :type '(repeat (cons (regexp :tag "Folder Regexp")
+ (choice (const :tag "Target mark" mark)
+ (const :tag "Refile mark" refile)
+ (const :tag "none" nil))))
+ :group 'wl-spam)
+
+
+(defun wl-spam-folder-guess-domain (folder-name)
+ (cond ((string= folder-name wl-spam-folder-name)
+ 'spam)
+ ((wl-string-match-member folder-name
+ wl-spam-undecided-folder-regexp-list)
+ 'undecided)
+ ((wl-string-match-member folder-name
+ wl-spam-ignored-folder-regexp-list)
+ 'ignore)
+ (t
+ 'good)))
+
+(defsubst wl-spam-map-spam-messages (folder numbers function &rest args)
+ (let ((total (length numbers)))
+ (elmo-with-progress-display (> total elmo-display-progress-threshold)
+ (elmo-spam-check-spam total "Checking spam...")
+ (dolist (number (elmo-spam-list-spam-messages (elmo-spam-processor)
+ folder
+ numbers))
+ (apply function number args)))
+ (message "Checking spam...done")))
+
+;; insinuate into summary mode
+(defvar wl-summary-spam-map nil)
+
+(unless wl-summary-spam-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "*" 'wl-summary-target-mark-spam)
+ (define-key map "o" 'wl-summary-refile-spam)
+ (define-key map "s" 'wl-summary-register-as-spam)
+ (define-key map "S" 'wl-summary-register-as-spam-all)
+ (define-key map "n" 'wl-summary-register-as-good)
+ (define-key map "N" 'wl-summary-register-as-good-all)
+ (setq wl-summary-spam-map map)
+ (define-key wl-summary-mode-map "k" wl-summary-spam-map)))
+
+(eval-when-compile
+ ;; Avoid compile warnings
+ (defalias-maybe 'wl-summary-target-mark 'ignore)
+ (defalias-maybe 'wl-summary-refile-mark 'ignore))
+
+(defun wl-summary-target-mark-spam (&optional folder)
+ "Set target mark to messages which is guessed spam in FOLDER."
+ (interactive)
+ (wl-spam-map-spam-messages (or folder wl-summary-buffer-elmo-folder)
+ wl-summary-buffer-number-list
+ #'wl-summary-target-mark))
+
+(defun wl-summary-refile-spam (&optional folder)
+ "Set refile mark to messages which is guessed spam in FOLDER."
+ (interactive)
+ (wl-spam-map-spam-messages (or folder wl-summary-buffer-elmo-folder)
+ wl-summary-buffer-number-list
+ #'wl-summary-refile
+ wl-spam-folder-name))
+
+(defun wl-summary-register-as-spam (&optional all)
+ (interactive "P")
+ (let ((numbers (if all
+ wl-summary-buffer-number-list
+ (list (wl-summary-message-number)))))
+ (elmo-spam-register-spam-messages (elmo-spam-processor)
+ wl-summary-buffer-elmo-folder
+ numbers)))
+
+(defun wl-summary-register-as-spam-all ()
+ (interactive)
+ (wl-summary-register-as-spam 'all))
+
+(defun wl-summary-register-as-good (&optional all)
+ (interactive "P")
+ (let ((numbers (if all
+ wl-summary-buffer-number-list
+ (list (wl-summary-message-number)))))
+ (elmo-spam-register-good-messages (elmo-spam-processor)
+ wl-summary-buffer-elmo-folder
+ numbers)))
+
+(defun wl-summary-register-as-good-all ()
+ (interactive)
+ (wl-summary-register-as-good 'all))
+
+;; hook functions and other
+(defun wl-summary-auto-check-spam ()
+ (case (cdr (elmo-string-matched-assoc (wl-summary-buffer-folder-name)
+ wl-spam-auto-check-policy-alist))
+ (mark
+ (wl-summary-target-mark-spam))
+ (refile
+ (wl-summary-refile-spam))))
+
+(defun wl-summary-exec-action-refile-with-register (mark-list)
+ (let ((processor (elmo-spam-processor))
+ (folder wl-summary-buffer-elmo-folder)
+ spam-list good-list)
+ (when (eq (wl-spam-folder-guess-domain
+ (elmo-folder-name-internal folder))
+ 'undecided)
+ (dolist (info mark-list)
+ (case (wl-spam-folder-guess-domain (nth 2 info))
+ (spam
+ (setq spam-list (cons (car info) spam-list)))
+ (good
+ (setq good-list (cons (car info) good-list)))))
+ (let ((total (+ (length spam-list) (length good-list))))
+ (elmo-with-progress-display (> total elmo-display-progress-threshold)
+ (elmo-spam-register total "Register spam...")
+ (when spam-list
+ (elmo-spam-register-spam-messages processor folder spam-list))
+ (when good-list
+ (elmo-spam-register-good-messages processor folder good-list)))
+ (message "Register spam...done")))
+ ;; execute refile messages
+ (wl-summary-exec-action-refile mark-list)))
+
+(defun wl-refile-guess-by-spam (entity)
+ (when (elmo-spam-message-spam-p (elmo-spam-processor)
+ wl-summary-buffer-elmo-folder
+ (elmo-message-entity-number entity))
+ wl-spam-folder-name))
+
+(require 'product)
+(product-provide (provide 'wl-spam) (require 'wl-version))
+
+;;; wl-sapm.el ends here