2002-09-25 Bj\e,Av\e(Brn Torkelsson <torkel@acc.umu.se>
[gnus] / lisp / nnimap.el
index b089e16..bac0a15 100644 (file)
@@ -55,6 +55,7 @@
 ;;   o What about Gnus's article editing, can we support it?  NO!
 ;;   o Use \Draft to support the draft group??
 ;;   o Duplicate suppression
+;;   o Rewrite UID SEARCH UID X as UID FETCH X (UID) for those with slow servers
 
 ;;; Code:
 
@@ -126,10 +127,10 @@ this:
 \(setq nnimap-split-rule '((\"INBOX.gnus-imap\"   \"From:.*gnus-imap\")
                          (\"INBOX.junk\"        \"Subject:.*buy\")))
 
-As you can see, `nnimap-split-rule' is a list of lists, where the first
-element in each \"rule\" is the name of the IMAP mailbox, and the
-second is a regexp that nnimap will try to match on the header to find
-a fit.
+As you can see, `nnimap-split-rule' is a list of lists, where the
+first element in each \"rule\" is the name of the IMAP mailbox (or the
+symbol `junk' if you want to remove the mail), and the second is a
+regexp that nnimap will try to match on the header to find a fit.
 
 The second element can also be a function.  In that case, it will be
 called narrowed to the headers with the first element of the rule as
@@ -279,9 +280,12 @@ typical complete file name would be
 (defvoo nnimap-nov-file-name-suffix ".novcache"
   "Suffix for NOV cache base filename.")
 
-(defvoo nnimap-nov-is-evil nil
-  "If non-nil, nnimap will never generate or use a local nov database for this backend.
-Using nov databases will speed up header fetching considerably.
+(defvoo nnimap-nov-is-evil gnus-agent
+  "If non-nil, never generate or use a local nov database for this backend.
+Using nov databases should speed up header fetching considerably.
+However, it will invoke a UID SEARCH UID command on the server, and
+some servers implement this command inefficiently by opening each and
+every message in the group, thus making it quite slow.
 Unlike other backends, you do not need to take special care if you
 flip this variable.")
 
@@ -377,7 +381,7 @@ restrict visible folders.")
 
 ;; Internal variables:
 
-(defvoo nnimap-mailbox-info (gnus-make-hashtable 997))
+(defvar nnimap-mailbox-info (gnus-make-hashtable 997))
 (defvar nnimap-debug nil
   "Name of buffer to record debugging info.
 For example: (setq nnimap-debug \"*nnimap-debug*\")")
@@ -966,7 +970,8 @@ function is generally only called when Gnus is shutting down."
            (setq slowgroups groups)
          (dolist (group groups)
            (gnus-message 7 "nnimap: Checking mailbox %s" group)
-           (add-to-list (if (gnus-gethash-safe group nnimap-mailbox-info)
+           (add-to-list (if (gnus-gethash-safe (concat server group)
+                                               nnimap-mailbox-info)
                             'asyncgroups
                           'slowgroups)
                         (list group (imap-mailbox-status-asynch
@@ -977,10 +982,12 @@ function is generally only called when Gnus is shutting down."
                  new old)
              (when (imap-ok-p (imap-wait-for-tag tag nnimap-server-buffer))
                (if (nnimap-string-lessp-numerical
-                    (car (gnus-gethash group nnimap-mailbox-info))
+                    (car (gnus-gethash
+                          (concat server group) nnimap-mailbox-info))
                     (imap-mailbox-get 'uidnext group nnimap-server-buffer))
                    (push (list group) slowgroups)
-                 (insert (cdr (gnus-gethash group nnimap-mailbox-info))))))))
+                 (insert (cdr (gnus-gethash (concat server group)
+                                            nnimap-mailbox-info))))))))
        (dolist (group slowgroups)
          (if nnimap-retrieve-groups-asynchronous
              (setq group (car group)))
@@ -999,7 +1006,7 @@ function is generally only called when Gnus is shutting down."
                (insert str)
                (when nnimap-retrieve-groups-asynchronous
                  (gnus-sethash
-                  group
+                  (concat server group)
                   (cons (or (imap-mailbox-get
                              'uidnext group nnimap-server-buffer)
                             (imap-mailbox-status
@@ -1147,7 +1154,10 @@ function is generally only called when Gnus is shutting down."
              (goto-char (point-min))
              (when (and (if (stringp regexp)
                             (progn
-                              (setq regrepp (string-match "\\\\[0-9&]" group))
+                              (if (not (stringp group))
+                                  (setq group (eval group))
+                                (setq regrepp
+                                      (string-match "\\\\[0-9&]" group)))
                               (re-search-forward regexp nil t))
                           (funcall regexp group))
                         ;; Don't enter the article into the same group twice.
@@ -1206,8 +1216,10 @@ function is generally only called when Gnus is shutting down."
                         (setq removeorig t)
                         (when nnmail-cache-accepted-message-ids
                           (with-current-buffer nntp-server-buffer
-                            (nnmail-cache-insert (nnmail-fetch-field
-                                                  "message-id") to-group)))
+                             (let (msgid)
+                               (and (setq msgid
+                                         (nnmail-fetch-field "message-id"))
+                                    (nnmail-cache-insert msgid to-group)))))
                         ;; Add the group-art list to the history list.
                         (push (list (cons to-group 0)) nnmail-split-history))
                        (t
@@ -1286,8 +1298,8 @@ function is generally only called when Gnus is shutting down."
 (defun nnimap-expiry-target (arts group server)
   (unless (eq nnmail-expiry-target 'delete)
     (with-temp-buffer
-      (dolist (art (gnus-uncompress-sequence arts))
-       (nnimap-request-article art group server  (current-buffer))
+      (dolist (art arts)
+       (nnimap-request-article art group server (current-buffer))
        ;; hints for optimization in `nnimap-request-accept-article'
        (let ((nnimap-current-move-article art)
              (nnimap-current-move-group group)
@@ -1302,35 +1314,32 @@ function is generally only called when Gnus is shutting down."
   (let ((artseq (gnus-compress-sequence articles)))
     (when (and artseq (nnimap-possibly-change-group group server))
       (with-current-buffer nnimap-server-buffer
-       (if force
-           (progn
-             (nnimap-expiry-target artseq group server)
-             (when (imap-message-flags-add (imap-range-to-message-set artseq)
-                                           "\\Deleted")
-               (setq articles nil)))
-         (let ((days (or (and nnmail-expiry-wait-function
-                              (funcall nnmail-expiry-wait-function group))
-                         nnmail-expiry-wait)))
-           (cond ((eq days 'immediate)
-                  (nnimap-expiry-target artseq group server)
-                  (when (imap-message-flags-add
-                         (imap-range-to-message-set artseq) "\\Deleted")
-                    (setq articles nil)))
-                 ((numberp days)
-                  (let ((oldarts (imap-search
-                                  (format nnimap-expunge-search-string
-                                          (imap-range-to-message-set artseq)
-                                          (nnimap-date-days-ago days))))
-                        (imap-fetch-data-hook
-                         '(nnimap-request-expire-articles-progress)))
+       (let ((days (or (and nnmail-expiry-wait-function
+                            (funcall nnmail-expiry-wait-function group))
+                       nnmail-expiry-wait)))
+         (cond ((or force (eq days 'immediate))
+                (let ((oldarts (imap-search
+                                (concat "UID " 
+                                        (imap-range-to-message-set artseq)))))
+                  (when oldarts
                     (nnimap-expiry-target oldarts group server)
-                    (and oldarts
-                         (imap-message-flags-add
-                          (imap-range-to-message-set
-                           (gnus-compress-sequence oldarts))
-                          "\\Deleted")
-                         (setq articles (gnus-set-difference
-                                         articles oldarts)))))))))))
+                    (when (imap-message-flags-add
+                           (imap-range-to-message-set oldarts) "\\Deleted")
+                      (setq articles (gnus-set-difference
+                                      articles oldarts))))))
+               ((numberp days)
+                (let ((oldarts (imap-search
+                                (format nnimap-expunge-search-string
+                                        (imap-range-to-message-set artseq)
+                                        (nnimap-date-days-ago days))))
+                      (imap-fetch-data-hook
+                       '(nnimap-request-expire-articles-progress)))
+                  (when oldarts
+                    (nnimap-expiry-target oldarts group server)
+                    (when (imap-message-flags-add
+                           (imap-range-to-message-set oldarts) "\\Deleted")
+                      (setq articles (gnus-set-difference 
+                                      articles oldarts)))))))))))
   ;; return articles not deleted
   articles)
 
@@ -1378,7 +1387,8 @@ function is generally only called when Gnus is shutting down."
                    (while (search-forward "\n" nil t)
                      (replace-match "\r\n"))
                    (when nnmail-cache-accepted-message-ids
-                     (nnmail-cache-insert (nnmail-fetch-field "message-id"))))
+                     (nnmail-cache-insert (nnmail-fetch-field "message-id")
+                                          group)))
                  (when (and last nnmail-cache-accepted-message-ids)
                    (nnmail-cache-close))
                  ;; this 'or' is for Cyrus server bug