* elsp-bsfilter.el (elmo-spam-bsfilter-max-files-per-process)
authorhmurata <hmurata>
Fri, 25 Aug 2006 14:34:58 +0000 (14:34 +0000)
committerhmurata <hmurata>
Fri, 25 Aug 2006 14:34:58 +0000 (14:34 +0000)
(elmo-spam-bsfilter-max-messages-per-process): New use option.
(elmo-spam-bsfilter-debug): Fix a group.
(elsp-bsfilter-call-bsfilter): Don't use `delq' and add option
`--homedir'.
(elmo-spam-buffer-spam-p): Don't specify `--homedir' option.
(elsp-bsfilter-list-spam-files): New function.
(elmo-spam-list-spam-messages): Define.
(elsp-bsfilter-register-buffer): Add an optional argument `mbox'.
(elmo-spam-bsfilter-register-messages): New function.
(elmo-spam-register-spam-messages): Define.
(elmo-spam-register-good-messages): Ditto.

* elmo-spam.el (elmo-spam-process-messages-as-mbox): New function.

elmo/ChangeLog
elmo/elmo-spam.el
elmo/elsp-bsfilter.el

index f2e6caf..bbe4206 100644 (file)
@@ -1,5 +1,20 @@
 2006-08-25  Hiroya Murata  <lapis-lazuli@pop06.odn.ne.jp>
 
+       * elsp-bsfilter.el (elmo-spam-bsfilter-max-files-per-process)
+       (elmo-spam-bsfilter-max-messages-per-process): New use option.
+       (elmo-spam-bsfilter-debug): Fix a group.
+       (elsp-bsfilter-call-bsfilter): Don't use `delq' and add option
+       `--homedir'.
+       (elmo-spam-buffer-spam-p): Don't specify `--homedir' option.
+       (elsp-bsfilter-list-spam-files): New function.
+       (elmo-spam-list-spam-messages): Define.
+       (elsp-bsfilter-register-buffer): Add an optional argument `mbox'.
+       (elmo-spam-bsfilter-register-messages): New function.
+       (elmo-spam-register-spam-messages): Define.
+       (elmo-spam-register-good-messages): Ditto.
+
+       * elmo-spam.el (elmo-spam-process-messages-as-mbox): New function.
+
        * elmo-util.el (elmo-flatten): Use `append' and `listp' instead of
        `nconc' and `consp'.
 
index e7580fe..3a05c8b 100644 (file)
@@ -129,6 +129,27 @@ If optional argument RESTORE is non-nil, unregister from spam list.")
      (elmo-find-fetch-strategy folder number nil 'entire)
      'unread)))
 
+(defun elmo-spam-process-messages-as-mbox (folder numbers number-per-process
+                                                 function &rest args)
+  (with-temp-buffer
+    (while numbers
+      (let ((count 0))
+       (while (and numbers (< count number-per-process))
+         (insert "From MAILER-DAEMON@example.com\n")
+         (let ((begin (point)))
+           (elmo-spam-message-fetch folder (car numbers))
+           (goto-char begin)
+           (while (re-search-forward "^>*From " nil t)
+             (goto-char (match-beginning 0))
+             (insert ?>)
+             (forward-line))
+           (goto-char (point-max))
+           (insert "\n\n"))
+         (setq count (1+ count)
+               numbers (cdr numbers)))
+       (apply function count args)
+       (erase-buffer)))))
+
 ;; generic implement
 (luna-define-method elmo-spam-message-spam-p ((processor elsp-generic)
                                              folder number &optional register)
index 98835ea..6ecf133 100644 (file)
                 (const :tag "Use the default"))
   :group 'elmo-spam-bsfilter)
 
+(defcustom elmo-spam-bsfilter-max-files-per-process 100
+  "Number of files processed at once."
+  :type 'integer
+  :group 'elmo-spam-bsfilter)
+
+(defcustom elmo-spam-bsfilter-max-messages-per-process 30
+  "Number of messages processed at once."
+  :type 'integer
+  :group 'elmo-spam-bsfilter)
+
 (defcustom elmo-spam-bsfilter-debug nil
   "Non-nil to debug elmo bsfilter spam backend."
   :type 'boolean
-  :group 'elmo-spam-bsfilter-debug)
+  :group 'elmo-spam-bsfilter)
 
 (eval-and-compile
   (luna-define-class elsp-bsfilter (elsp-generic)))
         elmo-spam-bsfilter-shell-program
         nil (if elmo-spam-bsfilter-debug
                 (get-buffer-create "*Debug ELMO Bsfilter*"))
-        nil (delq nil
-                  (append (list elmo-spam-bsfilter-shell-switch
-                                elmo-spam-bsfilter-program)
-                          elmo-spam-bsfilter-args
-                          (elmo-flatten args)))))
+        nil
+        (append (if elmo-spam-bsfilter-shell-switch
+                    (list elmo-spam-bsfilter-shell-switch))
+                (list elmo-spam-bsfilter-program)
+                elmo-spam-bsfilter-args
+                (if elmo-spam-bsfilter-database-directory
+                    (list "--homedir" elmo-spam-bsfilter-database-directory))
+                (elmo-flatten args))))
 
 (luna-define-method elmo-spam-buffer-spam-p ((processor elsp-bsfilter)
                                             buffer &optional register)
   (with-current-buffer buffer
     (= 0 (elsp-bsfilter-call-bsfilter
-         (if register elmo-spam-bsfilter-update-switch)
-         (if elmo-spam-bsfilter-database-directory
-             (list "--homedir" elmo-spam-bsfilter-database-directory))))))
-
-(defsubst elsp-bsfilter-register-buffer (buffer spam restore)
+         (if register elmo-spam-bsfilter-update-switch)))))
+
+(defsubst elsp-bsfilter-list-spam-files (targets)
+  (apply
+   #'call-process
+   elmo-spam-bsfilter-shell-program
+   nil
+   (list t (if elmo-spam-bsfilter-debug
+              (get-buffer-create "*Debug ELMO Bsfilter*")))
+   nil
+   (append (if elmo-spam-bsfilter-shell-switch
+              (list elmo-spam-bsfilter-shell-switch))
+          (list elmo-spam-bsfilter-program "--list-spam")
+          elmo-spam-bsfilter-args
+          (if elmo-spam-bsfilter-database-directory
+              (list "--homedir" elmo-spam-bsfilter-database-directory))
+          targets)))
+
+(luna-define-method elmo-spam-list-spam-messages :around
+  ((processor elsp-bsfilter) folder &optional numbers)
+  (if (not (elmo-folder-message-file-p folder))
+      (luna-call-next-method)
+    (let* ((nth-of-targets (1- (or elmo-spam-bsfilter-max-files-per-process
+                                  100)))
+          (numbers (or numbers (elmo-folder-list-messages folder t t)))
+          (hash (elmo-make-hash (length numbers)))
+          (targets (mapcar
+                    (lambda (number)
+                      (let ((filename (elmo-message-file-name folder number)))
+                        (elmo-set-hash-val filename number hash)
+                        filename))
+                    numbers))
+          results)
+      (with-temp-buffer
+       (while targets
+         (let* ((last (nthcdr nth-of-targets targets))
+                (next (cdr last)))
+           (when last
+             (setcdr last nil))
+           (elsp-bsfilter-list-spam-files targets)
+           (elmo-progress-notify 'elmo-spam-check-spam (length targets))
+           (setq targets next)))
+       (goto-char (point-min))
+       (while (not (eobp))
+         (let* ((filename (buffer-substring (point) (save-excursion
+                                                      (end-of-line)
+                                                      (point))))
+                (number (elmo-get-hash-val filename hash)))
+           (when number
+             (setq results (cons number results)))
+           (forward-line))))
+      results)))
+
+
+(defsubst elsp-bsfilter-register-buffer (buffer spam restore &optional mbox)
   (with-current-buffer buffer
     (elsp-bsfilter-call-bsfilter
      "--update"
-     (if elmo-spam-bsfilter-database-directory
-        (list "--homedir" elmo-spam-bsfilter-database-directory))
      (if restore (if spam "--sub-clean" "--sub-spam"))
-     (if spam "--add-spam" "--add-clean"))))
+     (if spam "--add-spam" "--add-clean")
+     (if mbox "--mbox"))))
 
 (luna-define-method elmo-spam-register-spam-buffer ((processor elsp-bsfilter)
                                                    buffer &optional restore)
                                                    buffer &optional restore)
   (elsp-bsfilter-register-buffer buffer nil restore))
 
+(defsubst elmo-spam-bsfilter-register-messages (folder numbers spam restore)
+  (let ((numbers (or numbers (elmo-folder-list-messages folder t t))))
+    (if (and (> (length numbers) 1)
+            elmo-spam-bsfilter-max-messages-per-process
+            (> elmo-spam-bsfilter-max-messages-per-process 0))
+       (elmo-spam-process-messages-as-mbox
+        folder numbers
+        elmo-spam-bsfilter-max-messages-per-process
+        (lambda (count spam restore)
+          (elsp-bsfilter-register-buffer (current-buffer) spam restore 'mbox)
+          (elmo-progress-notify 'elmo-spam-register count))
+        spam restore)
+      (luna-call-next-method))))
+
+(luna-define-method elmo-spam-register-spam-messages :around
+  ((processor elsp-bsfilter) folder &optional numbers restore)
+  (elmo-spam-bsfilter-register-messages folder numbers t restore))
+
+(luna-define-method elmo-spam-register-good-messages :around
+  ((processor elsp-bsfilter) folder &optional numbers restore)
+  (elmo-spam-bsfilter-register-messages folder numbers nil restore))
+
 (require 'product)
 (product-provide (provide 'elsp-bsfilter) (require 'elmo-version))