*** empty log message ***
[gnus] / lisp / gnus-cache.el
index 6e52f4f..94f69d4 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-cache.el --- cache interface for Gnus
-;; Copyright (C) 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
 ;; Keywords: news
@@ -17,8 +17,9 @@
 ;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; 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:
 
@@ -41,7 +42,7 @@
 (defvar gnus-cache-remove-articles '(read)
   "*Classes of articles to remove from the cache.")
 
-(defvar gnus-uncacheable-groups "^nnvirtual"
+(defvar gnus-uncacheable-groups nil
   "*Groups that match this regexp will not be cached.
 
 If you want to avoid caching your nnml groups, you could set this
@@ -56,7 +57,8 @@ variable to \"^nnml\".")
 (defvar gnus-cache-active-altered nil)
 
 (eval-and-compile
-  (autoload 'nnml-generate-nov-databases-1 "nnml"))
+  (autoload 'nnml-generate-nov-databases-1 "nnml")
+  (autoload 'nnvirtual-find-group-art "nnvirtual"))
 
 \f
 
@@ -106,11 +108,18 @@ variable to \"^nnml\".")
 
 (defun gnus-cache-possibly-enter-article 
   (group article headers ticked dormant unread &optional force)
-  (when (or force (not (eq gnus-use-cache 'passive)))
+  (when (and (or force (not (eq gnus-use-cache 'passive)))
+            (vectorp headers)) ; This might be a dummy article.
+    ;; If this is a virtual group, we find the real group.
+    (when (gnus-virtual-group-p group)
+      (let ((result (nnvirtual-find-group-art group article)))
+       (setq group (car result)
+             article (cdr result)
+             headers (copy-sequence headers))
+       (aset headers 0 article)))
     (let ((number (mail-header-number headers))
          file dir)
-      (when (and (vectorp headers)     ; This might be a dummy article.
-                (> number 0)           ; Reffed article.
+      (when (and (> number 0)          ; Reffed article.
                 (or (not gnus-uncacheable-groups)
                     (not (string-match gnus-uncacheable-groups group)))
                 (or force
@@ -124,59 +133,74 @@ variable to \"^nnml\".")
        ;; Save the article in the cache.
        (if (file-exists-p file)
            t                           ; The article already is saved.
-         (let ((gnus-use-cache nil))
-           (gnus-summary-select-article))
          (save-excursion
-           (set-buffer gnus-original-article-buffer)
-           (save-restriction
-             (widen)
-             (write-region (point-min) (point-max) file nil 'quiet))
-           (gnus-cache-change-buffer group)
-           (set-buffer (cdr gnus-cache-buffer))
-           (goto-char (point-max))
-           (forward-line -1)
-           (while (condition-case ()
-                      (and (not (bobp))
-                           (> (read (current-buffer)) number))
-                    (error
-                     ;; The line was malformed, so we just remove it!!
-                     (gnus-delete-line)
-                     t))
-             (forward-line -1))
-           (if (bobp) 
-               (if (not (eobp))
-                   (progn
-                     (beginning-of-line)
-                     (if (< (read (current-buffer)) number)
-                         (forward-line 1)))
-                 (beginning-of-line))
-             (forward-line 1))
-           (beginning-of-line)
-           ;; [number subject from date id references chars lines xref]
-           (insert (format "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n"
-                           (mail-header-number headers)
-                           (mail-header-subject headers)
-                           (mail-header-from headers)
-                           (mail-header-date headers)
-                           (mail-header-id headers)
-                           (or (mail-header-references headers) "")
-                           (or (mail-header-chars headers) "")
-                           (or (mail-header-lines headers) "")
-                           (or (mail-header-xref headers) ""))))
-         ;; Update the active info.
-         (gnus-cache-update-active group number)
-         (push number gnus-newsgroup-cached)
-         t)))))
+           (set-buffer nntp-server-buffer)
+           (let ((gnus-use-cache nil))
+             (gnus-request-article-this-buffer article group))
+           (when (> (buffer-size) 0)
+             (write-region (point-min) (point-max) file nil 'quiet)
+             (gnus-cache-change-buffer group)
+             (set-buffer (cdr gnus-cache-buffer))
+             (goto-char (point-max))
+             (forward-line -1)
+             (while (condition-case ()
+                        (and (not (bobp))
+                             (> (read (current-buffer)) number))
+                      (error
+                       ;; The line was malformed, so we just remove it!!
+                       (gnus-delete-line)
+                       t))
+               (forward-line -1))
+             (if (bobp) 
+                 (if (not (eobp))
+                     (progn
+                       (beginning-of-line)
+                       (if (< (read (current-buffer)) number)
+                           (forward-line 1)))
+                   (beginning-of-line))
+               (forward-line 1))
+             (beginning-of-line)
+             ;; [number subject from date id references chars lines xref]
+             (insert (format "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n"
+                             (mail-header-number headers)
+                             (mail-header-subject headers)
+                             (mail-header-from headers)
+                             (mail-header-date headers)
+                             (mail-header-id headers)
+                             (or (mail-header-references headers) "")
+                             (or (mail-header-chars headers) "")
+                             (or (mail-header-lines headers) "")
+                             (or (mail-header-xref headers) "")))
+             ;; Update the active info.
+             (set-buffer gnus-summary-buffer)
+             (gnus-cache-update-active group number)
+             (push number gnus-newsgroup-cached)
+             (gnus-summary-update-secondary-mark article))
+           t))))))
 
 (defun gnus-cache-enter-remove-article (article)
   "Mark ARTICLE for later possible removal."
-  (setq gnus-cache-removeable-articles
-       (cons article gnus-cache-removeable-articles)))
+  (when article
+    (push article gnus-cache-removable-articles)))
 
 (defun gnus-cache-possibly-remove-articles ()
+  "Possibly remove some of the removable articles."
+  (if (not (gnus-virtual-group-p gnus-newsgroup-name))
+      (gnus-cache-possibly-remove-articles-1)
+    (let ((arts gnus-cache-removable-articles)
+         ga)
+      (while arts
+       (when (setq ga (nnvirtual-find-group-art
+                       gnus-newsgroup-name (pop arts)))
+         (let ((gnus-cache-removable-articles (list (cdr ga)))
+               (gnus-newsgroup-name (car ga)))
+           (gnus-cache-possibly-remove-articles-1)))))
+    (setq gnus-cache-removable-articles nil)))
+
+(defun gnus-cache-possibly-remove-articles-1 ()
   "Possibly remove some of the removable articles."
   (unless (eq gnus-use-cache 'passive)
-    (let ((articles gnus-cache-removeable-articles)
+    (let ((articles gnus-cache-removable-articles)
          (cache-articles gnus-newsgroup-cached)
          article)
       (gnus-cache-change-buffer gnus-newsgroup-name)
@@ -249,7 +273,7 @@ variable to \"^nnml\".")
        (gnus-cache-braid-heads group cached)
        type)))))
 
-(defun gnus-cache-enter-article (n)
+(defun gnus-cache-enter-article (&optional n)
   "Enter the next N articles into the cache.
 If not given a prefix, use the process marked articles instead.
 Returns the list of articles entered."
@@ -329,7 +353,7 @@ Returns the list of articles removed."
             (let ((group (concat group "")))
               (if (string-match ":" group)
                   (aset group (match-beginning 0) ?/))
-              (gnus-replace-chars-in-string group ?. ?/))))
+              (nnheader-replace-chars-in-string group ?. ?/))))
          (if (stringp article) article (int-to-string article))))
 
 (defun gnus-cache-possibly-remove-article 
@@ -351,6 +375,7 @@ Returns the list of articles removed."
                           (progn (forward-line 1) (point)))))
       (setq gnus-newsgroup-cached
            (delq article gnus-newsgroup-cached))
+      (gnus-summary-update-secondary-mark article)
       t)))
 
 (defun gnus-cache-articles-in-group (group)
@@ -427,20 +452,25 @@ Returns the list of articles removed."
 (defun gnus-jog-cache ()
   "Go through all groups and put the articles into the cache."
   (interactive)
-  (let ((newsrc (cdr gnus-newsrc-alist))
-       (gnus-cache-enter-articles '(unread))
-       (gnus-mark-article-hook nil)
+  (let ((gnus-mark-article-hook nil)
        (gnus-expert-user t)
+       (nnmail-spool-file nil)
+       (gnus-use-dribble-file nil)
+       (gnus-novice-user nil)
        (gnus-large-newsgroup nil))
-    (while newsrc
-      (gnus-summary-read-group (car (car newsrc)))
-      (if (not (eq major-mode 'gnus-summary-mode))
-         ()
-       (while gnus-newsgroup-unreads
-         (gnus-summary-select-article t t nil (car gnus-newsgroup-unreads))
-         (setq gnus-newsgroup-unreads (cdr gnus-newsgroup-unreads)))
-       (kill-buffer (current-buffer)))
-      (setq newsrc (cdr newsrc)))))
+    ;; Start Gnus.
+    (gnus)
+    ;; Go through all groups...
+    (gnus-group-mark-buffer)
+    (gnus-group-universal-argument 
+     nil nil 
+     (lambda ()
+       (gnus-summary-read-group nil nil t)
+       ;; ... and enter the articles into the cache.
+       (when (eq major-mode 'gnus-summary-mode)
+        (gnus-uu-mark-buffer)
+        (gnus-cache-enter-article)
+        (kill-buffer (current-buffer)))))))
 
 (defun gnus-cache-read-active (&optional force)
   "Read the cache active file."
@@ -472,6 +502,7 @@ Returns the list of articles removed."
                           (symbol-name sym) (cdr (symbol-value sym))
                           (car (symbol-value sym))))))
        gnus-cache-active-hashtb)
+      (gnus-make-directory (file-name-directory gnus-cache-active-file))
       (write-region 
        (point-min) (point-max) gnus-cache-active-file nil 'silent))
     ;; Mark the active hashtb as unaltered.
@@ -499,13 +530,14 @@ If LOW, update the lower bound instead."
         (directory (expand-file-name (or directory gnus-cache-directory)))
         (files (directory-files directory 'full))
         (group 
-         (progn
+         (if top
+             ""
            (string-match 
             (concat "^" (file-name-as-directory
                          (expand-file-name gnus-cache-directory)))
-            directory)
-           (gnus-replace-chars-in-string 
-            (substring directory (match-end 0))
+            (directory-file-name directory))
+           (nnheader-replace-chars-in-string 
+            (substring (directory-file-name directory) (match-end 0))
             ?/ ?.)))
         nums alphs)
     (when top