(nnimap-open-server): Check imap-state in IMAP server
[gnus] / lisp / nnimap.el
index 381a6cf..4b22749 100644 (file)
@@ -528,10 +528,7 @@ If EXAMINE is non-nil the group is selected read-only."
        (with-temp-buffer
         (buffer-disable-undo)
         (insert headers)
-        (nnheader-ms-strip-cr)
-        (nnheader-fold-continuation-lines)
-        (subst-char-in-region (point-min) (point-max) ?\t ? )
-        (let ((head (nnheader-parse-head 'naked)))
+        (let ((head (nnheader-parse-naked-head)))
           (mail-header-set-number head uid)
           (mail-header-set-chars head chars)
           (mail-header-set-lines head lines)
@@ -734,7 +731,12 @@ If EXAMINE is non-nil the group is selected read-only."
     (with-current-buffer (get-buffer-create nnimap-server-buffer)
       (nnoo-change-server 'nnimap server defs))
     (or (and nnimap-server-buffer
-            (imap-opened nnimap-server-buffer))
+            (imap-opened nnimap-server-buffer)
+            (if (with-current-buffer nnimap-server-buffer
+                  (memq imap-state '(auth select examine)))
+                t
+              (imap-close nnimap-server-buffer)
+              (nnimap-open-connection server)))
        (nnimap-open-connection server))))
 
 (deffoo nnimap-server-opened (&optional server)
@@ -871,10 +873,22 @@ function is generally only called when Gnus is shutting down."
             (nnheader-report 'nnimap "Group %s selected" group)
             t)))))
 
+(defun nnimap-update-unseen (group &optional server)
+  "Update the unseen count in `nnimap-mailbox-info'."
+  (gnus-sethash
+   (gnus-group-prefixed-name group server)
+   (let ((old (gnus-gethash-safe (gnus-group-prefixed-name group server) 
+                                nnimap-mailbox-info)))
+     (list (nth 0 old) (nth 1 old)
+          (imap-mailbox-status group 'unseen nnimap-server-buffer)
+          (nth 3 old)))
+   nnimap-mailbox-info))
+
 (defun nnimap-close-group (group &optional server)
   (with-current-buffer nnimap-server-buffer
     (when (and (imap-opened)
               (nnimap-possibly-change-group group server))
+      (nnimap-update-unseen group server)
       (case nnimap-expunge-on-close
        (always (progn
                  (imap-mailbox-expunge nnimap-close-asynchronous)
@@ -969,29 +983,40 @@ function is generally only called when Gnus is shutting down."
        (if (null nnimap-retrieve-groups-asynchronous)
            (setq slowgroups groups)
          (dolist (group groups)
-           (gnus-message 7 "nnimap: Checking mailbox %s" group)
-           (add-to-list (if (gnus-gethash-safe (concat server group)
-                                               nnimap-mailbox-info)
+           (gnus-message 9 "nnimap: Quickly checking mailbox %s" group)
+           (add-to-list (if (gnus-gethash-safe
+                             (gnus-group-prefixed-name group server)
+                             nnimap-mailbox-info)
                             'asyncgroups
                           'slowgroups)
                         (list group (imap-mailbox-status-asynch
-                                     group 'uidnext nnimap-server-buffer))))
+                                     group '(uidvalidity uidnext unseen) 
+                                     nnimap-server-buffer))))
          (dolist (asyncgroup asyncgroups)
            (let ((group (nth 0 asyncgroup))
                  (tag   (nth 1 asyncgroup))
                  new old)
              (when (imap-ok-p (imap-wait-for-tag tag nnimap-server-buffer))
-               (if (nnimap-string-lessp-numerical
-                    (car (gnus-gethash
-                          (concat server group) nnimap-mailbox-info))
-                    (imap-mailbox-get 'uidnext group nnimap-server-buffer))
+               (if (or (not (string=
+                             (nth 0 (gnus-gethash (gnus-group-prefixed-name
+                                                   group server)
+                                                  nnimap-mailbox-info))
+                             (imap-mailbox-get 'uidvalidity group 
+                                               nnimap-server-buffer)))
+                       (not (string=
+                             (nth 1 (gnus-gethash (gnus-group-prefixed-name
+                                                   group server)
+                                                  nnimap-mailbox-info))
+                             (imap-mailbox-get 'uidnext group
+                                               nnimap-server-buffer))))
                    (push (list group) slowgroups)
-                 (insert (cdr (gnus-gethash (concat server group)
-                                            nnimap-mailbox-info))))))))
+                 (insert (nth 3 (gnus-gethash (gnus-group-prefixed-name
+                                               group server)
+                                              nnimap-mailbox-info))))))))
        (dolist (group slowgroups)
          (if nnimap-retrieve-groups-asynchronous
              (setq group (car group)))
-         (gnus-message 7 "nnimap: Rechecking mailbox %s" group)
+         (gnus-message 7 "nnimap: Mailbox %s modified" group)
          (imap-mailbox-put 'uidnext nil group nnimap-server-buffer)
          (or (member "\\NoSelect" (imap-mailbox-get 'list-flags group
                                                     nnimap-server-buffer))
@@ -1006,11 +1031,19 @@ function is generally only called when Gnus is shutting down."
                (insert str)
                (when nnimap-retrieve-groups-asynchronous
                  (gnus-sethash
-                  (concat server group)
-                  (cons (or (imap-mailbox-get
+                  (gnus-group-prefixed-name group server)
+                  (list (or (imap-mailbox-get
+                             'uidvalidity group nnimap-server-buffer)
+                            (imap-mailbox-status
+                             group 'uidvalidity nnimap-server-buffer))
+                        (or (imap-mailbox-get
                              'uidnext group nnimap-server-buffer)
                             (imap-mailbox-status
                              group 'uidnext nnimap-server-buffer))
+                        (or (imap-mailbox-get
+                             'unseen group nnimap-server-buffer)
+                            (imap-mailbox-status
+                             group 'unseen nnimap-server-buffer))
                         str)
                   nnimap-mailbox-info)))))))
     (gnus-message 5 "nnimap: Checking mailboxes...done")
@@ -1298,11 +1331,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 (imap-search (concat "UID " 
-                                       (imap-range-to-message-set
-                                        (gnus-uncompress-sequence arts)))
-                   nnimap-server-buffer))
-       (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)
@@ -1320,16 +1350,16 @@ function is generally only called when Gnus is shutting down."
        (let ((days (or (and nnmail-expiry-wait-function
                             (funcall nnmail-expiry-wait-function group))
                        nnmail-expiry-wait)))
-         (cond (force
-                (nnimap-expiry-target artseq group server)
-                (when (imap-message-flags-add
-                       (imap-range-to-message-set artseq) "\\Deleted")
-                  (setq articles nil)))
-               ((eq days 'immediate)
-                (nnimap-expiry-target artseq group server)
-                (when (imap-message-flags-add
-                       (imap-range-to-message-set artseq) "\\Deleted")
-                  (setq articles nil)))
+         (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)
+                    (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
@@ -1337,14 +1367,12 @@ function is generally only called when Gnus is shutting down."
                                         (nnimap-date-days-ago days))))
                       (imap-fetch-data-hook
                        '(nnimap-request-expire-articles-progress)))
-                  (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 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)