*** empty log message ***
[gnus] / lisp / gnus-cache.el
index 4dc700f..9329e69 100644 (file)
@@ -68,6 +68,8 @@ variable to \"^nnml\".")
   "Initialize the cache."
   (gnus-cache-read-active))
 
   "Initialize the cache."
   (gnus-cache-read-active))
 
+(gnus-add-shutdown 'gnus-cache-close 'gnus)
+
 (defun gnus-cache-close ()
   "Shut down the cache."
   (gnus-cache-write-active)
 (defun gnus-cache-close ()
   "Shut down the cache."
   (gnus-cache-write-active)
@@ -109,14 +111,16 @@ variable to \"^nnml\".")
 (defun gnus-cache-possibly-enter-article 
   (group article headers ticked dormant unread &optional force)
   (when (and (or force (not (eq gnus-use-cache 'passive)))
 (defun gnus-cache-possibly-enter-article 
   (group article headers ticked dormant unread &optional force)
   (when (and (or force (not (eq gnus-use-cache 'passive)))
+            (numberp article)
+            (> article 0)
             (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)
             (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)))
+      (let ((result (nnvirtual-find-group-art 
+                    (gnus-group-real-name group) article)))
        (setq group (car result)
        (setq group (car result)
-             article (cdr result)
              headers (copy-sequence headers))
              headers (copy-sequence headers))
-       (aset headers 0 article)))
+       (mail-header-set-number headers (cdr result))))
     (let ((number (mail-header-number headers))
          file dir)
       (when (and (> number 0)          ; Reffed article.
     (let ((number (mail-header-number headers))
          file dir)
       (when (and (> number 0)          ; Reffed article.
@@ -126,7 +130,7 @@ variable to \"^nnml\".")
                     (gnus-cache-member-of-class
                      gnus-cache-enter-articles ticked dormant unread))
                 (not (file-exists-p (setq file (gnus-cache-file-name
                     (gnus-cache-member-of-class
                      gnus-cache-enter-articles ticked dormant unread))
                 (not (file-exists-p (setq file (gnus-cache-file-name
-                                                group article)))))
+                                                group number)))))
        ;; Possibly create the cache directory.
        (or (file-exists-p (setq dir (file-name-directory file)))
            (gnus-make-directory dir))
        ;; Possibly create the cache directory.
        (or (file-exists-p (setq dir (file-name-directory file)))
            (gnus-make-directory dir))
@@ -136,7 +140,7 @@ variable to \"^nnml\".")
          (save-excursion
            (set-buffer nntp-server-buffer)
            (let ((gnus-use-cache nil))
          (save-excursion
            (set-buffer nntp-server-buffer)
            (let ((gnus-use-cache nil))
-             (gnus-request-article-this-buffer article group))
+             (gnus-request-article-this-buffer number group))
            (when (> (buffer-size) 0)
              (write-region (point-min) (point-max) file nil 'quiet)
              (gnus-cache-change-buffer group)
            (when (> (buffer-size) 0)
              (write-region (point-min) (point-max) file nil 'quiet)
              (gnus-cache-change-buffer group)
@@ -174,7 +178,7 @@ variable to \"^nnml\".")
              ;; Update the active info.
              (set-buffer gnus-summary-buffer)
              (gnus-cache-update-active group number)
              ;; Update the active info.
              (set-buffer gnus-summary-buffer)
              (gnus-cache-update-active group number)
-             (push number gnus-newsgroup-cached)
+             (push article gnus-newsgroup-cached)
              (gnus-summary-update-secondary-mark article))
            t))))))
 
              (gnus-summary-update-secondary-mark article))
            t))))))
 
@@ -191,7 +195,7 @@ variable to \"^nnml\".")
          ga)
       (while arts
        (when (setq ga (nnvirtual-find-group-art
          ga)
       (while arts
        (when (setq ga (nnvirtual-find-group-art
-                       gnus-newsgroup-name (pop arts)))
+                       (gnus-group-real-name gnus-newsgroup-name) (pop arts)))
          (let ((gnus-cache-removable-articles (list (cdr ga)))
                (gnus-newsgroup-name (car ga)))
            (gnus-cache-possibly-remove-articles-1)))))
          (let ((gnus-cache-removable-articles (list (cdr ga)))
                (gnus-newsgroup-name (car ga)))
            (gnus-cache-possibly-remove-articles-1)))))
@@ -239,39 +243,49 @@ variable to \"^nnml\".")
 
 (defun gnus-cache-retrieve-headers (articles group &optional fetch-old)
   "Retrieve the headers for ARTICLES in GROUP."
 
 (defun gnus-cache-retrieve-headers (articles group &optional fetch-old)
   "Retrieve the headers for ARTICLES in GROUP."
-  (let* ((cached 
-         (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group)))
-        (articles (gnus-sorted-complement articles cached))
-        (cache-file (gnus-cache-file-name group ".overview"))
-        type)
-    ;; We first retrieve all the headers that we don't have in 
-    ;; the cache.
-    (let ((gnus-use-cache nil))
-      (setq type (and articles 
-                     (gnus-retrieve-headers articles group fetch-old))))
-    (gnus-cache-save-buffers)
-    ;; Then we insert the cached headers.
-    (save-excursion
-      (cond
-       ((not (file-exists-p cache-file))
-       ;; There are no cached headers.
-       type)
-       ((null type)
-       ;; There were no uncached headers (or retrieval was 
-       ;; unsuccessful), so we use the cached headers exclusively.
-       (set-buffer nntp-server-buffer)
-       (erase-buffer)
-       (insert-file-contents cache-file)
-       'nov)
-       ((eq type 'nov)
-       ;; We have both cached and uncached NOV headers, so we
-       ;; braid them.
-       (gnus-cache-braid-nov group cached)
-       type)
-       (t
-       ;; We braid HEADs.
-       (gnus-cache-braid-heads group cached)
-       type)))))
+  (let ((cached 
+        (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group))))
+    (if (not cached)
+       ;; No cached articles here, so we just retrieve them
+       ;; the normal way.
+       (let ((gnus-use-cache nil))
+         (gnus-retrieve-headers articles group fetch-old))
+      (let ((uncached-articles (gnus-sorted-intersection
+                               (gnus-sorted-complement articles cached)
+                               articles))
+           (cache-file (gnus-cache-file-name group ".overview"))
+           type)
+       ;; We first retrieve all the headers that we don't have in 
+       ;; the cache.
+       (let ((gnus-use-cache nil))
+         (when uncached-articles
+           (setq type (and articles 
+                           (gnus-retrieve-headers 
+                            uncached-articles group fetch-old)))))
+       (gnus-cache-save-buffers)
+       ;; Then we insert the cached headers.
+       (save-excursion
+         (cond
+          ((not (file-exists-p cache-file))
+           ;; There are no cached headers.
+           type)
+          ((null type)
+           ;; There were no uncached headers (or retrieval was 
+           ;; unsuccessful), so we use the cached headers exclusively.
+           (set-buffer nntp-server-buffer)
+           (erase-buffer)
+           (insert-file-contents cache-file)
+           'nov)
+          ((eq type 'nov)
+           ;; We have both cached and uncached NOV headers, so we
+           ;; braid them.
+           (gnus-cache-braid-nov group cached)
+           type)
+          (t
+           ;; We braid HEADs.
+           (gnus-cache-braid-heads group (gnus-sorted-intersection
+                                          cached articles))
+           type)))))))
 
 (defun gnus-cache-enter-article (&optional n)
   "Enter the next N articles into the cache.
 
 (defun gnus-cache-enter-article (&optional n)
   "Enter the next N articles into the cache.
@@ -299,6 +313,7 @@ If not given a prefix, use the process marked articles instead.
 Returns the list of articles removed."
   (interactive "P")
   (gnus-set-global-variables)
 Returns the list of articles removed."
   (interactive "P")
   (gnus-set-global-variables)
+  (gnus-cache-change-buffer gnus-newsgroup-name)
   (let ((articles (gnus-summary-work-articles n))
        article out)
     (while articles
   (let ((articles (gnus-summary-work-articles n))
        article out)
     (while articles
@@ -307,6 +322,7 @@ Returns the list of articles removed."
        (push article out))
       (gnus-summary-remove-process-mark article)
       (gnus-summary-update-secondary-mark article))
        (push article out))
       (gnus-summary-remove-process-mark article)
       (gnus-summary-update-secondary-mark article))
+    (gnus-summary-next-subject 1)
     (gnus-summary-position-point)
     (nreverse out)))
 
     (gnus-summary-position-point)
     (nreverse out)))
 
@@ -344,7 +360,7 @@ Returns the list of articles removed."
   (or (and ticked (memq 'ticked class))
       (and dormant (memq 'dormant class))
       (and unread (memq 'unread class))
   (or (and ticked (memq 'ticked class))
       (and dormant (memq 'dormant class))
       (and unread (memq 'unread class))
-      (and (not unread) (memq 'read class))))
+      (and (not unread) (not ticked) (not dormant) (memq 'read class))))
 
 (defun gnus-cache-file-name (group article)
   (concat (file-name-as-directory gnus-cache-directory)
 
 (defun gnus-cache-file-name (group article)
   (concat (file-name-as-directory gnus-cache-directory)
@@ -364,10 +380,19 @@ Returns the list of articles removed."
      gnus-newsgroup-name article (gnus-summary-article-header article)
      nil nil nil t)))
 
      gnus-newsgroup-name article (gnus-summary-article-header article)
      nil nil nil t)))
 
-(defun gnus-cache-possibly-remove-article 
-  (article ticked dormant unread &optional force)
+(defun gnus-cache-possibly-remove-article (article ticked dormant unread 
+                                                  &optional force)
   "Possibly remove ARTICLE from the cache."
   "Possibly remove ARTICLE from the cache."
-  (let ((file (gnus-cache-file-name gnus-newsgroup-name article)))
+  (let ((group gnus-newsgroup-name)
+       (number article)
+       file)
+    ;; If this is a virtual group, we find the real group.
+    (when (gnus-virtual-group-p group)
+      (let ((result (nnvirtual-find-group-art 
+                    (gnus-group-real-name group) article)))
+       (setq group (car result)
+             number (cdr result))))
+    (setq file (gnus-cache-file-name group number))
     (when (and (file-exists-p file)
               (or force
                   (gnus-cache-member-of-class
     (when (and (file-exists-p file)
               (or force
                   (gnus-cache-member-of-class
@@ -376,8 +401,8 @@ Returns the list of articles removed."
        (delete-file file)
        (set-buffer (cdr gnus-cache-buffer))
        (goto-char (point-min))
        (delete-file file)
        (set-buffer (cdr gnus-cache-buffer))
        (goto-char (point-min))
-       (if (or (looking-at (concat (int-to-string article) "\t"))
-               (search-forward (concat "\n" (int-to-string article) "\t")
+       (if (or (looking-at (concat (int-to-string number) "\t"))
+               (search-forward (concat "\n" (int-to-string number) "\t")
                                (point-max) t))
            (delete-region (progn (beginning-of-line) (point))
                           (progn (forward-line 1) (point)))))
                                (point-max) t))
            (delete-region (progn (beginning-of-line) (point))
                           (progn (forward-line 1) (point)))))
@@ -447,7 +472,9 @@ Returns the list of articles removed."
        (erase-buffer)
        (insert-file-contents (gnus-cache-file-name group (car cached)))
        (goto-char (point-min))
        (erase-buffer)
        (insert-file-contents (gnus-cache-file-name group (car cached)))
        (goto-char (point-min))
-       (insert "220 " (int-to-string (car cached)) " Article retrieved.\n")
+       (insert "220 ")
+       (princ (car cached) (current-buffer))
+       (insert " Article retrieved.\n")
        (search-forward "\n\n" nil 'move)
        (delete-region (point) (point-max))
        (forward-char -1)
        (search-forward "\n\n" nil 'move)
        (delete-region (point) (point-max))
        (forward-char -1)
@@ -482,6 +509,8 @@ Returns the list of articles removed."
 
 (defun gnus-cache-read-active (&optional force)
   "Read the cache active file."
 
 (defun gnus-cache-read-active (&optional force)
   "Read the cache active file."
+  (unless (file-exists-p gnus-cache-directory)
+    (make-directory gnus-cache-directory t))
   (if (not (and (file-exists-p gnus-cache-active-file)
                (or force (not gnus-cache-active-hashtb))))
       ;; There is no active file, so we generate one.
   (if (not (and (file-exists-p gnus-cache-active-file)
                (or force (not gnus-cache-active-hashtb))))
       ;; There is no active file, so we generate one.