(elmo-shimbun-update-overview): Add argnument
[elisp/wanderlust.git] / elmo / elsp-bogofilter.el
index e4eec9c..8548650 100644 (file)
   :type '(repeat 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-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)
 
+(defcustom elmo-spam-bogofilter-max-messages-per-process 30
+  "Number of messages processed at once."
+  :type 'integer
+  :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-arguments-alist
+  '((classify
+     (if elmo-spam-bogofilter-debug "-vv")
+     (if register "-u")
+     (if elmo-spam-bogofilter-database-directory
+        (list "-d" elmo-spam-bogofilter-database-directory)))
+    (register
+     (if elmo-spam-bogofilter-debug "-vv")
+     (if spam "-s" "-n")
+     (if restore (if spam "-N" "-S"))
+     (if elmo-spam-bogofilter-database-directory
+        (list "-d" elmo-spam-bogofilter-database-directory))))
+  "*An alist of options that are used with call bogofilter process.
+Each element is a list of following:
+\(TYPE [SEXP...])
+TYPE is a symbol from `classify' or `register'.
+SEXP is an expression to get options.
+Must be return a string or list of string."
+  :type '(repeat (cons (choice (const :tag "Classify" classify)
+                              (const :tag "Register" register))
+                      (repeat sexp)))
+  :group 'elmo-spam-bogofilter)
+
+(defcustom elmo-spam-bogofilter-debug nil
+  "Non-nil to debug elmo bogofilter spam backend."
+  :type 'boolean
+  :group 'elmo-spam-bogofilter)
+
+
 (eval-and-compile
   (luna-define-class elsp-bogofilter (elsp-generic)))
 
-(defsubst elsp-bogofilter-call-bogofilter (&rest args)
+(defsubst elmo-spam-bogofilter-call (&optional args)
   (apply #'call-process-region
         (point-min) (point-max)
         elmo-spam-bogofilter-program
-        nil nil nil
+        nil (if elmo-spam-bogofilter-debug
+                (get-buffer-create "*Debug ELMO SPAM Bogofilter*"))
+        nil
         (append elmo-spam-bogofilter-args
-                (delq nil (elmo-flatten args)))))
+                (delq nil args))))
+
+(defmacro elmo-spam-bogofilter-arguments (type)
+  `(elmo-flatten
+    (mapcar #'eval
+           (cdr (assq ,type elmo-spam-bogofilter-arguments-alist)))))
 
 (luna-define-method elmo-spam-buffer-spam-p ((processor elsp-bogofilter)
                                             buffer &optional register)
   (with-current-buffer buffer
-    (= 0 (elsp-bogofilter-call-bogofilter
-         "-v" "-2"
-         (if register "-u")
-         (if elmo-spam-bogofilter-database-directory
-             (list "-d" elmo-spam-bogofilter-database-directory))))))
+    (= 0 (elmo-spam-bogofilter-call
+         (elmo-spam-bogofilter-arguments 'classify)))))
 
 (defsubst elsp-bogofilter-register-buffer (buffer spam restore)
   (with-current-buffer buffer
-    (elsp-bogofilter-call-bogofilter
-     "-v"
-     (if spam
-        elmo-spam-bogofilter-spam-switch
-       elmo-spam-bogofilter-good-switch)
-     (if restore (if spam "-N" "-S"))
-     (if elmo-spam-bogofilter-database-directory
-        (list "-d" elmo-spam-bogofilter-database-directory)))))
+    (elmo-spam-bogofilter-call
+     (elmo-spam-bogofilter-arguments 'register))))
 
 (luna-define-method elmo-spam-register-spam-buffer ((processor elsp-bogofilter)
                                                    buffer &optional restore)
                                                    buffer &optional restore)
   (elsp-bogofilter-register-buffer buffer nil restore))
 
+(defsubst elmo-spam-bogofilter-register-messages (folder numbers spam restore)
+  (if (not (< 0 elmo-spam-bogofilter-max-messages-per-process))
+      (error "\
+non-positive value for `elmo-spam-bogofilter-max-messages-per-process'"))
+  (elmo-spam-process-messages-as-mbox
+   folder numbers elmo-spam-bogofilter-max-messages-per-process
+   (lambda (count spam restore)
+     (elsp-bogofilter-register-buffer (current-buffer) spam restore)
+     (elmo-progress-notify 'elmo-spam-register count))
+   spam restore))
+
+(luna-define-method elmo-spam-register-spam-messages :around
+  ((processor elsp-bogofilter) folder &optional numbers restore)
+  (let ((numbers (or numbers (elmo-folder-list-messages folder t t))))
+    (if (> (length numbers) 1)
+       (elmo-spam-bogofilter-register-messages folder numbers t restore)
+      (luna-call-next-method))))
+
+(luna-define-method elmo-spam-register-good-messages :around
+  ((processor elsp-bogofilter) folder &optional numbers restore)
+  (let ((numbers (or numbers (elmo-folder-list-messages folder t t))))
+    (if (> (length numbers) 1)
+       (elmo-spam-bogofilter-register-messages folder numbers nil restore)
+      (luna-call-next-method))))
+
 (require 'product)
 (product-provide (provide 'elsp-bogofilter) (require 'elmo-version))