2001-01-16 Jesper Harder <harder@ifa.au.dk>
[gnus] / lisp / gnus-nocem.el
index 0695668..d682451 100644 (file)
@@ -1,7 +1,8 @@
 ;;; gnus-nocem.el --- NoCeM pseudo-cancellation treatment
-;; Copyright (C) 1995,96,97 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
 
 ;; This file is part of GNU Emacs.
@@ -25,6 +26,8 @@
 
 ;;; Code:
 
+(eval-when-compile (require 'cl))
+
 (require 'gnus)
 (require 'nnmail)
 (require 'gnus-art)
 (defcustom gnus-nocem-groups
   '("news.lists.filters" "news.admin.net-abuse.bulletins"
     "alt.nocem.misc" "news.admin.net-abuse.announce")
-  "List of groups that will be searched for NoCeM messages."
+  "*List of groups that will be searched for NoCeM messages."
   :group 'gnus-nocem
   :type '(repeat (string :tag "Group")))
 
 (defcustom gnus-nocem-issuers
- '("AutoMoose-1" "Automoose-1"   ; CancelMoose[tm]
-   "rbraver@ohww.norman.ok.us"   ; Robert Braver
-   "clewis@ferret.ocunix.on.ca;" ; Chris Lewis
-   "jem@xpat.com;"              ; Despammer from Korea
-   "snowhare@xmission.com"       ; Benjamin "Snowhare" Franz
-   "red@redpoll.mrfs.oh.us (Richard E. Depew)" ; ARMM! ARMM!
-   )
-  "List of NoCeM issuers to pay attention to."
+  '("AutoMoose-1"                      ; CancelMoose[tm]
+    "clewis@ferret.ocunix"             ; Chris Lewis
+    "cosmo.roadkill"
+    "SpamHippo"
+    "hweede@snafu.de")
+  "*List of NoCeM issuers to pay attention to.
+
+This can also be a list of `(ISSUER CONDITION ...)' elements.
+
+See <URL:http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html> for an
+issuer registry."
   :group 'gnus-nocem
-  :type '(repeat string))
+  :type '(repeat (choice string sexp)))
 
 (defcustom gnus-nocem-directory
   (nnheader-concat gnus-article-save-directory "NoCeM/")
@@ -80,6 +86,21 @@ matches an previously scanned and verified nocem message."
   :group 'gnus-nocem
   :type 'boolean)
 
+(defcustom gnus-nocem-check-article-limit 500
+  "*If non-nil, the maximum number of articles to check in any NoCeM group."
+  :group 'gnus-nocem
+  :version "21.1"
+  :type '(choice (const :tag "unlimited" nil)
+                (integer 1000)))
+
+(defcustom gnus-nocem-check-from t
+  "Non-nil means check for valid issuers in message bodies.
+Otherwise don't bother fetching articles unless their author matches a
+valid issuer, which is much faster if you are selective about the issuers."
+  :group 'gnus-nocem
+  :version "21.1"
+  :type 'boolean)
+
 ;;; Internal variables
 
 (defvar gnus-nocem-active nil)
@@ -96,15 +117,33 @@ matches an previously scanned and verified nocem message."
 (defun gnus-nocem-cache-file ()
   (concat (file-name-as-directory gnus-nocem-directory) "cache"))
 
+;;
+;; faster lookups for group names:
+;;
+
+(defvar gnus-nocem-real-group-hashtb nil
+  "Real-name mappings of subscribed groups.")
+
+(defun gnus-fill-real-hashtb ()
+  "Fill up a hash table with the real-name mappings from the user's active file."
+  (setq gnus-nocem-real-group-hashtb (gnus-make-hashtable
+                                     (length gnus-newsrc-alist)))
+  (mapcar (lambda (group)
+           (setq group (gnus-group-real-name (car group)))
+           (gnus-sethash group t gnus-nocem-real-group-hashtb))
+         gnus-newsrc-alist))
+
 (defun gnus-nocem-scan-groups ()
   "Scan all NoCeM groups for new NoCeM messages."
   (interactive)
   (let ((groups gnus-nocem-groups)
        (gnus-inhibit-demon t)
-       group active gactive articles)
+       group active gactive articles check-headers)
     (gnus-make-directory gnus-nocem-directory)
     ;; Load any previous NoCeM headers.
     (gnus-nocem-load-cache)
+    ;; Get the group name mappings:
+    (gnus-fill-real-hashtb)
     ;; Read the active file if it hasn't been read yet.
     (and (file-exists-p (gnus-nocem-active-file))
         (not gnus-nocem-active)
@@ -124,7 +163,7 @@ matches an previously scanned and verified nocem message."
          (save-excursion
            (let ((dependencies (make-vector 10 nil))
                  headers header)
-             (nnheader-temp-write nil
+             (with-temp-buffer
                (setq headers
                      (if (eq 'nov
                              (gnus-retrieve-headers
@@ -145,13 +184,34 @@ matches an previously scanned and verified nocem message."
                  ;; are not allowed to have references, so we can
                  ;; ignore scanning followups.
                  (and (string-match "@@NCM" (mail-header-subject header))
+                      (and gnus-nocem-check-from
+                           (let ((case-fold-search t))
+                             (catch 'ok
+                               (mapcar
+                                (lambda (author)
+                                  (if (consp author)
+                                      (setq author (car author)))
+                                  (if (string-match
+                                       author (mail-header-from header))
+                                      (throw 'ok t)))
+                                gnus-nocem-issuers)
+                               nil)))
                       (or gnus-nocem-liberal-fetch
                           (and (or (string= "" (mail-header-references
                                                 header))
                                    (null (mail-header-references header)))
                                (not (member (mail-header-message-id header)
                                             gnus-nocem-seen-message-ids))))
-                      (gnus-nocem-check-article group header)))))))
+                      (push header check-headers)))
+               (let* ((i 0)
+                      (check-headers
+                       (last check-headers gnus-nocem-check-article-limit))
+                      (len (length check-headers)))
+                 (dolist (h check-headers)