(message-tool-bar-gnome): Rename "mail/attach" to "attach".
[gnus] / lisp / nnkiboze.el
index e887bc6..9e176f3 100644 (file)
@@ -1,5 +1,7 @@
 ;;; nnkiboze.el --- select virtual news access for Gnus
-;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
+
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004,
+;;   2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
@@ -18,8 +20,8 @@
 
 ;; 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.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
@@ -34,6 +36,7 @@
 (require 'gnus)
 (require 'gnus-score)
 (require 'nnoo)
+(require 'mm-util)
 (eval-when-compile (require 'cl))
 
 (nnoo-declare nnkiboze)
@@ -55,6 +58,9 @@
 (defvoo nnkiboze-regexp nil
   "Regexp for matching component groups.")
 
+(defvoo nnkiboze-file-coding-system mm-text-coding-system
+  "Coding system for nnkiboze files.")
+
 \f
 
 (defconst nnkiboze-version "nnkiboze 1.0")
@@ -80,7 +86,8 @@
          (save-excursion
            (set-buffer nntp-server-buffer)
            (erase-buffer)
-           (nnheader-insert-file-contents nov)
+           (let ((nnheader-file-coding-system nnkiboze-file-coding-system))
+             (nnheader-insert-file-contents nov))
            (nnheader-nov-delete-outside-range
             (car articles) (car (last articles)))
            'nov))))))
       ;; article fetching by message-id at all.
       (nntp-request-article article newsgroup gnus-nntp-server buffer)
     (let* ((header (gnus-summary-article-header article))
-          (xref (mail-header-xref header)))
+          (xref (mail-header-xref header))
+          num group)
       (unless xref
        (error "nnkiboze: No xref"))
       (unless (string-match " \\([^ ]+\\):\\([0-9]+\\)" xref)
        (error "nnkiboze: Malformed xref"))
-      (gnus-request-article (string-to-int (match-string 2 xref))
-                           (match-string 1 xref)
-                           buffer))))
+      (setq num (string-to-number (match-string 2 xref))
+           group (match-string 1 xref))
+      (or (with-current-buffer buffer
+           (or (and gnus-use-cache (gnus-cache-request-article num group))
+               (gnus-agent-request-article num group)))
+         (gnus-request-article num group buffer)))))
 
 (deffoo nnkiboze-request-scan (&optional group server)
+  (nnkiboze-possibly-change-group group)
   (nnkiboze-generate-group (concat "nnkiboze:" group)))
 
 (deffoo nnkiboze-request-group (group &optional server dont-check)
          (nnkiboze-request-scan group))
        (if (not (file-exists-p nov-file))
            (nnheader-report 'nnkiboze "Can't select group %s" group)
-         (nnheader-insert-file-contents nov-file)
+         (let ((nnheader-file-coding-system nnkiboze-file-coding-system))
+           (nnheader-insert-file-contents nov-file))
          (if (zerop (buffer-size))
              (nnheader-insert "211 0 0 0 %s\n" group)
            (goto-char (point-min))
   ;; Remove NOV lines of articles that are marked as read.
   (when (and (file-exists-p (nnkiboze-nov-file-name))
             nnkiboze-remove-read-articles)
-    (nnheader-temp-write (nnkiboze-nov-file-name)
-      (let ((cur (current-buffer)))
-       (nnheader-insert-file-contents (nnkiboze-nov-file-name))
-       (goto-char (point-min))
-       (while (not (eobp))
-         (if (not (gnus-article-read-p (read cur)))
-             (forward-line 1)
-           (gnus-delete-line))))))
-  (setq nnkiboze-current-group nil))
+    (let ((coding-system-for-write nnkiboze-file-coding-system))
+      (with-temp-file (nnkiboze-nov-file-name)
+       (let ((cur (current-buffer))
+             (nnheader-file-coding-system nnkiboze-file-coding-system))
+         (nnheader-insert-file-contents (nnkiboze-nov-file-name))
+         (goto-char (point-min))
+         (while (not (eobp))
+           (if (not (gnus-article-read-p (read cur)))
+               (forward-line 1)
+             (gnus-delete-line))))))
+    (setq nnkiboze-current-group nil)))
 
 (deffoo nnkiboze-open-server (server &optional defs)
   (unless (assq 'nnkiboze-regexp defs)
 (deffoo nnkiboze-request-delete-group (group &optional force server)
   (nnkiboze-possibly-change-group group)
   (when force
-     (let ((files (nconc
-                  (nnkiboze-score-file group)
-                  (list (nnkiboze-nov-file-name)
-                        (concat nnkiboze-directory
-                                (nnheader-translate-file-chars
-                                 (concat group ".newsrc")))))))
-       (while files
-        (and (file-exists-p (car files))
-             (file-writable-p (car files))
-             (delete-file (car files)))
-        (setq files (cdr files)))))
+    (let ((files (nconc
+                 (nnkiboze-score-file group)
+                 (list (nnkiboze-nov-file-name)
+                       (nnkiboze-nov-file-name ".newsrc")))))
+      (while files
+       (and (file-exists-p (car files))
+            (file-writable-p (car files))
+            (delete-file (car files)))
+       (setq files (cdr files)))))
   (setq nnkiboze-current-group nil)
   t)
 
 
 ;;;###autoload
 (defun nnkiboze-generate-groups ()
-  "Usage: emacs -batch -l nnkiboze -f nnkiboze-generate-groups
+  "\"Usage: emacs -batch -l nnkiboze -f nnkiboze-generate-groups\".
 Finds out what articles are to be part of the nnkiboze groups."
   (interactive)
   (let ((nnmail-spool-file nil)
+       (mail-sources nil)
        (gnus-use-dribble-file nil)
        (gnus-read-active-file t)
        (gnus-expert-user t))
@@ -200,7 +214,10 @@ Finds out what articles are to be part of the nnkiboze groups."
       (when (string-match "nnkiboze" (gnus-info-group info))
        ;; For each kiboze group, we call this function to generate
        ;; it.
-       (nnkiboze-generate-group (gnus-info-group info))))))
+       (nnkiboze-generate-group (gnus-info-group info) t))))
+  (save-excursion
+    (set-buffer gnus-group-buffer)
+    (gnus-group-list-groups)))
 
 (defun nnkiboze-score-file (group)
   (list (expand-file-name
@@ -209,134 +226,137 @@ Finds out what articles are to be part of the nnkiboze groups."
                  (concat (nnkiboze-prefixed-name nnkiboze-current-group)
                          "." gnus-score-file-suffix))))))
 
-(defun nnkiboze-generate-group (group)
-  (let* ((info (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))
-        (newsrc-file (concat nnkiboze-directory 
-                              (nnheader-translate-file-chars
-                               (concat group ".newsrc"))))
+(defun nnkiboze-generate-group (group &optional inhibit-list-groups)
+  (let* ((info (gnus-get-info group))
+        (newsrc-file (concat nnkiboze-directory
+                             (nnheader-translate-file-chars
+                              (concat group ".newsrc"))))
         (nov-file (concat nnkiboze-directory
-                           (nnheader-translate-file-chars
-                            (concat group ".nov"))))
+                          (nnheader-translate-file-chars
+                           (concat group ".nov"))))
         method nnkiboze-newsrc gname newsrc active
         ginfo lowest glevel orig-info nov-buffer
         ;; Bind various things to nil to make group entry faster.
         (gnus-expert-user t)
         (gnus-large-newsgroup nil)
         (gnus-score-find-score-files-function 'nnkiboze-score-file)
+        ;; Use only nnkiboze-score-file!
+        (gnus-score-use-all-scores nil)
+        (gnus-use-scoring t)
         (gnus-verbose (min gnus-verbose 3))
-        gnus-select-group-hook gnus-summary-prepare-hook
+        gnus-select-group-hook gnus-summary-prepare-hook
         gnus-thread-sort-functions gnus-show-threads
         gnus-visual gnus-suppress-duplicates num-unread)
     (unless info
       (error "No such group: %s" group))
     ;; Load the kiboze newsrc file for this group.
-    (when (file-exists-p newsrc-file)
-      (load newsrc-file))
-    (nnheader-temp-write nov-file
-      (when (file-exists-p nov-file)
-       (insert-file-contents nov-file))
-      (setq nov-buffer (current-buffer))
-      ;; Go through the active hashtb and add new all groups that match the
-      ;; kiboze regexp.
-      (mapatoms
-       (lambda (group)
-        (and (string-match nnkiboze-regexp
-                           (setq gname (symbol-name group))) ; Match
-             (not (assoc gname nnkiboze-newsrc)) ; It isn't registered
-             (numberp (car (symbol-value group))) ; It is active
-             (or (> nnkiboze-level 7)
-                 (and (setq glevel (nth 1 (nth 2 (gnus-gethash
-                                                  gname gnus-newsrc-hashtb))))
-                      (>= nnkiboze-level glevel)))
-             (not (string-match "^nnkiboze:" gname)) ; Exclude kibozes
-             (push (cons gname (1- (car (symbol-value group))))
-                   nnkiboze-newsrc)))
-       gnus-active-hashtb)
-      ;; `newsrc' is set to the list of groups that possibly are
-      ;; component groups to this kiboze group.  This list has elements
-      ;; on the form `(GROUP . NUMBER)', where NUMBER is the highest
-      ;; number that has been kibozed in GROUP in this kiboze group.
-      (setq newsrc nnkiboze-newsrc)
-      (while newsrc
-       (if (not (setq active (gnus-gethash
-                              (caar newsrc) gnus-active-hashtb)))
-           ;; This group isn't active after all, so we remove it from
-           ;; the list of component groups.
-           (setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc))
-         (setq lowest (cdar newsrc))
-         ;; Ok, we have a valid component group, so we jump to it.
-         (switch-to-buffer gnus-group-buffer)
-         (gnus-group-jump-to-group (caar newsrc))
-         (gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc))
-         (setq ginfo (gnus-get-info (gnus-group-group-name))
-               orig-info (gnus-copy-sequence ginfo)
-               num-unread (car (gnus-gethash (caar newsrc)
-                                             gnus-newsrc-hashtb)))
-         (unwind-protect
-             (progn
-               ;; We set all list of article marks to nil.  Since we operate
-               ;; on copies of the real lists, we can destroy anything we
-               ;; want here.
-               (when (nth 3 ginfo)
-                 (setcar (nthcdr 3 ginfo) nil))
-               ;; We set the list of read articles to be what we expect for
-               ;; this kiboze group -- either nil or `(1 . LOWEST)'.
+    (mm-with-unibyte
+      (when (file-exists-p newsrc-file)
+       (load newsrc-file))
+      (let ((coding-system-for-write nnkiboze-file-coding-system))
+       (gnus-make-directory (file-name-directory nov-file))
+       (with-temp-file nov-file
+         (when (file-exists-p nov-file)
+           (insert-file-contents nov-file))
+         (setq nov-buffer (current-buffer))
+         ;; Go through the active hashtb and add new all groups that match the
+         ;; kiboze regexp.
+         (mapatoms
+          (lambda (group)
+            (and (string-match nnkiboze-regexp
+                               (setq gname (symbol-name group))) ; Match
+                 (not (assoc gname nnkiboze-newsrc)) ; It isn't registered
+                 (numberp (car (symbol-value group))) ; It is active
+                 (or (> nnkiboze-level 7)
+                     (and (setq glevel
+                                (gnus-info-level (gnus-get-info gname)))
+                          (>= nnkiboze-level glevel)))
+                 (not (string-match "^nnkiboze:" gname)) ; Exclude kibozes
+                 (push (cons gname (1- (car (symbol-value group))))
+                       nnkiboze-newsrc)))
+          gnus-active-hashtb)
+         ;; `newsrc' is set to the list of groups that possibly are
+         ;; component groups to this kiboze group.  This list has elements
+         ;; on the form `(GROUP . NUMBER)', where NUMBER is the highest
+         ;; number that has been kibozed in GROUP in this kiboze group.
+         (setq newsrc nnkiboze-newsrc)
+         (while newsrc
+           (if (not (setq active (gnus-active (caar newsrc))))
+               ;; This group isn't active after all, so we remove it from
+               ;; the list of component groups.
+               (setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc))
+             (setq lowest (cdar newsrc))
+             ;; Ok, we have a valid component group, so we jump to it.
+             (switch-to-buffer gnus-group-buffer)
+             (gnus-group-jump-to-group (caar newsrc))
+             (gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc))
+             (setq ginfo (gnus-get-info (gnus-group-group-name))
+                   orig-info (gnus-copy-sequence ginfo)
+                   num-unread (gnus-group-unread (caar newsrc)))
+             (unwind-protect
+                 (progn
+                   ;; We set all list of article marks to nil.  Since we operate
+                   ;; on copies of the real lists, we can destroy anything we
+                   ;; want here.
+                   (when (nth 3 ginfo)
+                     (setcar (nthcdr 3 ginfo) nil))
+                   ;; We set the list of read articles to be what we expect for
+                   ;; this kiboze group -- either nil or `(1 . LOWEST)'.