Synch up with main trunk.
[elisp/wanderlust.git] / elmo / elmo.el
index b059bd2..642834e 100644 (file)
@@ -1,4 +1,4 @@
-;;; elmo.el -- Elisp Library for Message Orchestration
+;;; elmo.el --- Elisp Library for Message Orchestration.
 
 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
 
@@ -77,7 +77,7 @@ Otherwise, entire fetching of the message is aborted without confirmation."
 (elmo-define-error 'elmo-error "Error" 'error)
 (elmo-define-error 'elmo-open-error "Cannot open" 'elmo-error)
 (elmo-define-error 'elmo-authenticate-error "Login failed" 'elmo-open-error)
-(elmo-define-error 'elmo-imap4-bye-error "IMAP4 BYE response" 'elmo-open-error)
+(elmo-define-error 'elmo-imap4-bye-error "IMAP4 session was terminated" 'elmo-open-error)
 
 (defun elmo-define-folder (prefix backend)
   "Define a folder.
@@ -109,6 +109,7 @@ If a folder name begins with PREFIX, use BACKEND."
                                     message-modified ; message is modified.
                                     mark-modified    ; mark is modified.
                                     process-duplicates  ; read or hide
+                                    biff   ; folder for biff
                                     ))
   (luna-define-internal-accessors 'elmo-folder))
 
@@ -193,7 +194,9 @@ If optional KEEP-KILLED is non-nil, killed-list is not cleared.")
   "Get diff of FOLDER.
 If optional NUMBERS is set, it is used as current NUMBERS.
 Otherwise, saved status for folder is used for comparison.
-Return value is a cons cell of NEWS and MESSAGES.")
+Return value is cons cell or list:
+ - a cons cell (NEWS . MESSAGES)
+ - a list (RECENT UNSEEN MESSAGES) ; RECENT means NEWS, UNSEEN means UNREAD.")
 
 (luna-define-generic elmo-folder-status (folder)
   "Returns a cons cell of (MAX-NUMBER . MESSAGES) in the FOLDER.")
@@ -244,7 +247,7 @@ IMPORTANT-MARK is the important mark."
                                 (elmo-object-load
                                  (expand-file-name
                                   elmo-msgdb-global-mark-filename
-                                  elmo-msgdb-dir)))))
+                                  elmo-msgdb-directory)))))
       (if (and (string= important-mark (cdr mark-pair))
               (setq num-pair (rassoc (car mark-pair) number-alist)))
          (setq result (cons (car num-pair) result))))
@@ -600,6 +603,12 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
 (luna-define-generic elmo-folder-append-msgdb (folder append-msgdb)
   "Append  APPEND-MSGDB to the current msgdb of the folder.")
 
+(luna-define-generic elmo-folder-newsgroups (folder)
+  "Return list of newsgroup name of FOLDER.")
+
+(luna-define-method elmo-folder-newsgroups ((folder elmo-folder))
+  nil)
+
 (luna-define-method elmo-folder-open ((folder elmo-folder)
                                      &optional load-msgdb)
   (elmo-generic-folder-open folder load-msgdb))
@@ -678,6 +687,9 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
 (luna-define-method elmo-folder-writable-p ((folder elmo-folder))
   nil) ; default is not writable.
 
+(luna-define-method elmo-folder-delete ((folder elmo-folder))
+  (elmo-msgdb-delete-path folder))
+
 (luna-define-method elmo-folder-rename ((folder elmo-folder) new-name)
   (let* ((new-folder (elmo-make-folder new-name)))
     (unless (eq (elmo-folder-type-internal folder)
@@ -771,6 +783,20 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
      info-alist)
     (setq elmo-folder-info-hashtb hashtb)))
 
+(defsubst elmo-diff-new (diff)
+  (when (consp (cdr diff))
+    (car diff)))
+
+(defsubst elmo-diff-unread (diff)
+  (if (consp (cdr diff))
+      (nth 1 diff)
+    (car diff)))
+
+(defsubst elmo-diff-all (diff)
+  (if (consp (cdr diff))
+      (nth 2 diff)
+    (cdr diff)))
+
 (defsubst elmo-strict-folder-diff (folder)
   "Return folder diff information strictly from FOLDER."
   (let* ((dir (elmo-folder-msgdb-path folder))
@@ -863,29 +889,35 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
       (while numbers
        (setq failure nil)
        (condition-case nil
-           (progn
-             (elmo-message-fetch
-              src-folder (car numbers)
-              (if (and (not (elmo-folder-plugged-p src-folder))
-                       elmo-enable-disconnected-operation
-                       (setq cache (elmo-file-cache-get
-                                    (elmo-message-field
-                                     src-folder (car numbers)
-                                     'message-id)))
-                       (eq (elmo-file-cache-status cache) 'entire))
-                  (elmo-make-fetch-strategy
-                   'entire t nil (elmo-file-cache-path cache))
-                (elmo-make-fetch-strategy 'entire t))
-              nil (current-buffer)
-              'unread)
-             (unless (eq (buffer-size) 0)
-               (setq failure (not
-                              (elmo-folder-append-buffer
-                               folder
-                               (setq unseen (member (elmo-message-mark
-                                                     src-folder (car numbers))
-                                                    unread-marks))
-                               (if same-number (car numbers)))))))
+           (setq cache (elmo-file-cache-get
+                        (elmo-message-field src-folder
+                                            (car numbers)
+                                            'message-id))
+                 failure
+                 (not
+                  (and
+                   (elmo-message-fetch
+                    src-folder (car numbers)
+                    (if (elmo-folder-plugged-p src-folder)
+                        (elmo-make-fetch-strategy
+                         'entire 'maybe nil
+                         (and cache (elmo-file-cache-path cache)))
+                      (or (and elmo-enable-disconnected-operation
+                               cache
+                               (eq (elmo-file-cache-status cache) 'entire)
+                               (elmo-make-fetch-strategy
+                                'entire t nil
+                                (elmo-file-cache-path cache)))
+                          (error "Unplugged")))
+                    nil (current-buffer)
+                    'unread)
+                   (> (buffer-size) 0)
+                   (elmo-folder-append-buffer
+                    folder
+                    (setq unseen (member (elmo-message-mark
+                                          src-folder (car numbers))
+                                         unread-marks))
+                    (if same-number (car numbers))))))
          (error (setq failure t)))
        ;; FETCH & APPEND finished
        (unless failure
@@ -1099,9 +1131,10 @@ FIELD is a symbol of the field."
 (defun elmo-folder-confirm-appends (appends)
   (let ((len (length appends))
        in)
-    (if (and (> len elmo-folder-update-threshold)
+    (if (and elmo-folder-update-threshold
+            (> len elmo-folder-update-threshold)
             elmo-folder-update-confirm)
-       (if (y-or-n-p (format "Too many messages(%d).  Continue? " len))
+       (if (y-or-n-p (format "Too many messages(%d).  Update all? " len))
            appends
          (setq in elmo-folder-update-threshold)
          (catch 'end
@@ -1111,11 +1144,12 @@ FIELD is a symbol of the field."
                    in (string-to-int in))
              (if (< len in)
                  (throw 'end len))
-             (if (y-or-n-p (format "%d messages are disappeared.  OK? "
+             (if (y-or-n-p (format "%d messages are not appeared.  OK? "
                                    (max (- len in) 0)))
                  (throw 'end in))))
          (nthcdr (max (- len in) 0) appends))
-      (if (and (> len elmo-folder-update-threshold)
+      (if (and elmo-folder-update-threshold
+              (> len elmo-folder-update-threshold)
               (not elmo-folder-update-confirm))
          (nthcdr (max (- len elmo-folder-update-threshold) 0) appends)
        appends))))
@@ -1130,8 +1164,7 @@ FIELD is a symbol of the field."
       (with-current-buffer outbuf
        (erase-buffer)
        (elmo-message-fetch-with-cache-process folder number
-                                              strategy section unread)
-       t)
+                                              strategy section unread))
     (with-temp-buffer
       (elmo-message-fetch-with-cache-process folder number
                                             strategy section unread)
@@ -1141,24 +1174,37 @@ FIELD is a symbol of the field."
                                                           number strategy
                                                           &optional
                                                           section unread)
-  (let (cache-path cache-file)
-    (if (and (elmo-fetch-strategy-use-cache strategy)
-            (setq cache-path (elmo-fetch-strategy-cache-path strategy))
-            (setq cache-file (elmo-file-cache-expand-path
-                              cache-path
-                              section))
-            (file-exists-p cache-file)
-            (or (not (elmo-cache-path-section-p cache-file))
-                (not (eq (elmo-fetch-strategy-entireness strategy) 'entire))))
-       (insert-file-contents-as-binary cache-file)
-      (elmo-message-fetch-internal folder number strategy section unread)
-      (elmo-delete-cr-buffer)
-      (when (and (> (buffer-size) 0)
-                (elmo-fetch-strategy-save-cache strategy)
-                (elmo-fetch-strategy-cache-path strategy))
-       (elmo-file-cache-save
-        (elmo-fetch-strategy-cache-path strategy)
-        section)))))
+  (let ((cache-path (elmo-fetch-strategy-cache-path strategy))
+       (method-priorities
+        (cond ((eq (elmo-fetch-strategy-use-cache strategy) 'meybe)
+               '(entity cache))
+              ((elmo-fetch-strategy-use-cache strategy)
+               '(cache entity))
+              (t
+               '(entity))))
+       result err)
+    (while (and method-priorities
+               (null result))
+      (setq result
+           (case (car method-priorities)
+             (cache
+              (elmo-file-cache-load cache-path section))
+             (entity
+              (when (and (condition-case error
+                             (elmo-message-fetch-internal folder number
+                                                          strategy
+                                                          section
+                                                          unread)
+                           (error (setq err error) nil))
+                         (> (buffer-size) 0))
+                (elmo-delete-cr-buffer)
+                (when (and (elmo-fetch-strategy-save-cache strategy)
+                           cache-path)
+                  (elmo-file-cache-save cache-path section))
+                t)))
+           method-priorities (cdr method-priorities)))
+    (or result
+       (and err (signal (car err) (cdr err))))))
 
 (luna-define-method elmo-folder-clear ((folder elmo-folder)
                                       &optional keep-killed)
@@ -1167,7 +1213,7 @@ FIELD is a symbol of the field."
   (elmo-folder-set-msgdb-internal folder (elmo-msgdb-clear)))
 
 (defun elmo-folder-synchronize (folder
-                               new-mark             ;"N"
+                               new-mark             ;"N"
                                unread-uncached-mark ;"U"
                                unread-cached-mark   ;"!"
                                read-uncached-mark   ;"u"
@@ -1181,7 +1227,7 @@ are mark strings for new messages, unread but cached messages,
 read but not cached messages, and important messages.
 If optional IGNORE-MSGDB is non-nil, current msgdb is thrown away except
 read mark status. If IGNORE-MSGDB is 'visible-only, only visible messages
-\(the messages which are not in the killed-list\) are thrown away and 
+\(the messages which are not in the killed-list\) are thrown away and
 synchronized.
 If NO-CHECK is non-nil, rechecking folder is skipped.
 
@@ -1232,16 +1278,7 @@ If update process is interrupted, return nil."
                              (length new-list)))
                     (setq diff-2 (elmo-list-diff (car diff) new-list)))
            (elmo-msgdb-append-to-killed-list folder (car diff-2)))
-         ;; Don't delete important marked messages.
-         (setq delete-list
-               (if (eq (elmo-folder-type-internal folder) 'mark)
-                   (cadr diff)
-                 (elmo-delete-if
-                  (lambda (x)
-                    (and (setq mark (cadr (assq x mark-alist)))
-                         (string= mark important-mark)))
-                  ;; delete message list
-                  (cadr diff))))
+         (setq delete-list (cadr diff))
          (if (or (equal diff '(nil nil))
                  (equal diff '(nil))
                  (and (eq (length (car diff)) 0)
@@ -1380,7 +1417,7 @@ Return a hashtable for newsgroups."
       (elmo-crosspost-alist-save elmo-crosspost-message-alist)
       (setq elmo-crosspost-message-alist-modified nil))))
 
-(defun elmo-folder-make-temp-dir (folder)
+(defun elmo-folder-make-temporary-directory (folder)
   ;; Make a temporary directory for FOLDER.
   (let ((temp-dir (make-temp-name
                   (concat
@@ -1453,6 +1490,17 @@ Return a hashtable for newsgroups."
                               'elmo-pop3-default-authenticate-type)
 (elmo-define-obsolete-variable 'elmo-default-pop3-port
                               'elmo-pop3-default-port)
+(elmo-define-obsolete-variable 'elmo-cache-dirname
+                              'elmo-cache-directory)
+(elmo-define-obsolete-variable 'elmo-msgdb-dir
+                              'elmo-msgdb-directory)
+
+;; Obsolete functions.
+;; 2001-12-11: *-dir -> *-directory
+(defalias 'elmo-folder-make-temp-dir 'elmo-folder-make-temporary-directory)
+(make-obsolete 'elmo-folder-make-temp-dir
+              'elmo-folder-make-temporary-directory)
+
 
 ;; autoloads
 (autoload 'elmo-dop-queue-flush "elmo-dop")