X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Felmo.el;h=b61152c00cb2ca8f294164dda0df74eeabe22e38;hb=bd1c7daca8de303dd5766cb7831e964cfe3a03c5;hp=8da60b2c829aec22c20ba960eecec81d76249782;hpb=8f80f667a307348e553d8d0d85bbcbca07341d05;p=elisp%2Fwanderlust.git diff --git a/elmo/elmo.el b/elmo/elmo.el index 8da60b2..b61152c 100644 --- a/elmo/elmo.el +++ b/elmo/elmo.el @@ -124,8 +124,7 @@ If a folder name begins with PREFIX, use BACKEND." ;;;###autoload (defun elmo-make-folder (name &optional non-persistent) "Make an ELMO folder structure specified by NAME. -If optional argument NON-PERSISTENT is non-nil, folder is treated as - non-persistent." +If optional argument NON-PERSISTENT is non-nil, the folder msgdb is not saved." (let ((type (elmo-folder-type name)) prefix split class folder original) (setq original (elmo-string name)) @@ -141,23 +140,26 @@ If optional argument NON-PERSISTENT is non-nil, folder is treated as (setq class (format "elmo-%s" (symbol-name type))) (require (intern class)) (setq folder (luna-make-entity (intern (concat class "-folder")) - :type type + :type type :prefix prefix :name original :persistent (not non-persistent))) (save-match-data (elmo-folder-send folder 'elmo-folder-initialize name)))) -(defmacro elmo-folder-msgdb (folder) - "Return the msgdb of FOLDER (on-demand loading)." - (` (or (elmo-folder-msgdb-internal (, folder)) - (elmo-folder-set-msgdb-internal (, folder) - (elmo-msgdb-load (, folder)))))) +;; Note that this function is for internal use only. +(luna-define-generic elmo-folder-msgdb (folder) + "Return the msgdb of FOLDER (on-demand loading). +\(For internal use only.\)") +(luna-define-method elmo-folder-msgdb ((folder elmo-folder)) + (or (elmo-folder-msgdb-internal folder) + (elmo-folder-set-msgdb-internal folder + (elmo-msgdb-load folder)))) (luna-define-generic elmo-folder-open (folder &optional load-msgdb) "Open and setup (load saved status) FOLDER. If optional LOAD-MSGDB is non-nil, msgdb is loaded. -(otherwise, msgdb is loaded on-demand)") +\(otherwise, msgdb is loaded on-demand)") (luna-define-generic elmo-folder-open-internal (folder) "Open FOLDER (without loading saved folder status).") @@ -190,13 +192,11 @@ If optional KEEP-KILLED is non-nil, killed-list is not cleared.") (luna-define-generic elmo-folder-use-flag-p (folder) "Returns t if FOLDER treats unread/important flag itself.") -(luna-define-generic elmo-folder-diff (folder &optional numbers) +(luna-define-generic elmo-folder-diff (folder) "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 cons cell or list: - - a cons cell (NEWS . MESSAGES) - - a list (RECENT UNSEEN MESSAGES) ; RECENT means NEWS, UNSEEN means UNREAD.") + - a cons cell (new . all) + - a list (new unread all)") (luna-define-generic elmo-folder-status (folder) "Returns a cons cell of (MAX-NUMBER . MESSAGES) in the FOLDER.") @@ -204,56 +204,75 @@ Return value is cons cell or list: (luna-define-generic elmo-folder-reserve-status-p (folder) "If non-nil, the folder should not close folder after `elmo-folder-status'.") -(defun elmo-folder-list-messages (folder &optional visible-only) +(luna-define-generic elmo-folder-list-messages (folder &optional visible-only + in-msgdb) "Return a list of message numbers contained in FOLDER. -If optional VISIBLE-ONLY is non-nil, killed messages are not listed." - (let ((list (elmo-folder-list-messages-internal folder visible-only)) - (killed (elmo-folder-killed-list-internal folder)) - numbers) - (setq numbers - (if (listp list) - list - ;; Not available, use current list. - (mapcar - 'car - (elmo-msgdb-get-number-alist (elmo-folder-msgdb folder))))) - (elmo-living-messages numbers killed))) - -(defun elmo-folder-list-unreads (folder unread-marks) - "Return a list of unread message numbers contained in FOLDER. -UNREAD-MARKS is the unread marks." - (let ((list (elmo-folder-list-unreads-internal folder - unread-marks))) - (if (listp list) - list - ;; Not available, use current mark. - (delq nil - (mapcar - (function - (lambda (x) - (if (member (cadr x) unread-marks) - (car x)))) - (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder))))))) - -(defun elmo-folder-list-importants (folder important-mark) - "Returns a list of important message numbers contained in FOLDER. -IMPORTANT-MARK is the important mark." - (let ((importants (elmo-folder-list-importants-internal folder important-mark)) - (number-alist (elmo-msgdb-get-number-alist - (elmo-folder-msgdb folder))) - num-pair result) +If optional VISIBLE-ONLY is non-nil, killed messages are not listed. +If second optional IN-MSGDB is non-nil, only messages in the msgdb are listed.") +(luna-define-method elmo-folder-list-messages ((folder elmo-folder) + &optional visible-only in-msgdb) + (let ((list (if in-msgdb + t + (elmo-folder-list-messages-internal folder visible-only)))) + (elmo-living-messages + (if (listp list) + list + ;; Use current list. + (elmo-msgdb-list-messages (elmo-folder-msgdb folder))) + (elmo-folder-killed-list-internal folder)))) + +(luna-define-generic elmo-folder-list-unreads (folder) + "Return a list of unread message numbers contained in FOLDER.") +(luna-define-generic elmo-folder-list-importants (folder) + "Return a list of important message numbers contained in FOLDER.") +(luna-define-generic elmo-folder-list-answereds (folder) + "Return a list of answered message numbers contained in FOLDER.") + +;; TODO: Should reconsider the structure of global mark. +(defun elmo-folder-list-messages-with-global-mark (folder mark) + (let (entity msgs) (dolist (mark-pair (or elmo-msgdb-global-mark-alist (setq elmo-msgdb-global-mark-alist (elmo-object-load (expand-file-name elmo-msgdb-global-mark-filename 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)))) - (if (listp importants) - (elmo-uniq-list (nconc result importants)) - result))) + (if (and (string= mark (cdr mark-pair)) + (setq entity + (elmo-msgdb-overview-get-entity (car mark-pair) + (elmo-folder-msgdb + folder)))) + (setq msgs (cons (elmo-msgdb-overview-entity-get-number entity) + msgs)))) + msgs)) + +(luna-define-generic elmo-folder-list-flagged (folder flag &optional in-msgdb) + "List messages in the FOLDER with FLAG. +FLAG is a symbol which is one of the following: + `new' (new messages) + `unread' (unread messages (new messages are included)) + `answered' (answered or forwarded) + `important' (marked as important) +'sugar' flags: + `read' (not unread) + `digest' (unread + important) + `any' (digest + answered) + +If optional IN-MSGDB is non-nil, retrieve flag information from msgdb.") + +(luna-define-method elmo-folder-list-flagged ((folder elmo-folder) flag + &optional in-msgdb) + ;; Currently, only in-msgdb is implemented. + (elmo-msgdb-list-flagged (elmo-folder-msgdb folder) flag)) + +(luna-define-method elmo-folder-list-unreads ((folder elmo-folder)) + (elmo-folder-list-flagged folder 'unread)) + +(luna-define-method elmo-folder-list-importants ((folder elmo-folder)) + (elmo-folder-list-flagged folder 'important)) + +(luna-define-method elmo-folder-list-answereds ((folder elmo-folder)) + (elmo-folder-list-flagged folder 'answered)) (luna-define-generic elmo-folder-list-messages-internal (folder &optional visible-only) @@ -261,24 +280,10 @@ IMPORTANT-MARK is the important mark." ;; Return t if the message list is not available. ) -(luna-define-generic elmo-folder-list-unreads-internal (folder - unread-marks - &optional mark-alist) - ;; Return a list of unread message numbers contained in FOLDER. - ;; If optional MARK-ALIST is set, it is used as mark-alist. - ;; Return t if this feature is not available. - ) - -(luna-define-generic elmo-folder-list-importants-internal (folder - important-mark) - ;; Return a list of important message numbers contained in FOLDER. - ;; Return t if this feature is not available. - ) - (luna-define-generic elmo-folder-list-subfolders (folder &optional one-level) "Returns a list of subfolders contained in FOLDER. If optional argument ONE-LEVEL is non-nil, only children of FOLDER is returned. -(a folder which have children is returned as a list) +\(a folder which have children is returned as a list\) Otherwise, all descendent folders are returned.") (luna-define-generic elmo-folder-have-subfolder-p (folder) @@ -328,46 +333,63 @@ CONDITION is a condition structure for testing. NUMBERS is a list of message numbers, use to be test for \"last\" and \"first\" predicates.") -(luna-define-generic elmo-folder-msgdb-create - (folder numbers new-mark already-mark seen-mark important-mark seen-list) +(luna-define-generic elmo-folder-msgdb-create (folder numbers flag-table) "Create a message database (implemented in each backends). FOLDER is the ELMO folder structure. NUMBERS is a list of message numbers to create msgdb. -NEW-MARK, ALREADY-MARK, SEEN-MARK, and IMPORTANT-MARK are mark string for -new message, unread but cached message, read message and important message. -SEEN-LIST is a list of message-id string which should be treated as read.") +FLAG-TABLE is a hashtable of message-id and flag.") -(luna-define-generic elmo-folder-unmark-important (folder numbers) +(luna-define-generic elmo-folder-unmark-important (folder + numbers + &optional ignore-flags) "Un-mark messages as important. FOLDER is the ELMO folder structure. -NUMBERS is a list of message numbers to be processed.") +NUMBERS is a list of message numbers to be processed. +If IGNORE-FLAGS is non-nil, folder flags are not updated.") -(luna-define-generic elmo-folder-mark-as-important (folder numbers) +(luna-define-generic elmo-folder-mark-as-important (folder + numbers + &optional ignore-flags) "Mark messages as important. FOLDER is the ELMO folder structure. -NUMBERS is a list of message numbers to be processed.") +NUMBERS is a list of message numbers to be processed. +If IGNORE-FLAGS is non-nil, folder flags are not updated.") -(luna-define-generic elmo-folder-unmark-read (folder numbers) +(luna-define-generic elmo-folder-unmark-read (folder numbers + &optional ignore-flags) "Un-mark messages as read. FOLDER is the ELMO folder structure. -NUMBERS is a list of message numbers to be processed.") +NUMBERS is a list of message numbers to be processed. +If IGNORE-FLAGS is non-nil, folder flags are not updated.") -(luna-define-generic elmo-folder-mark-as-read (folder numbers) +(luna-define-generic elmo-folder-mark-as-read (folder numbers + &optional ignore-flags) "Mark messages as read. FOLDER is the ELMO folder structure. +NUMBERS is a list of message numbers to be processed. +If IGNORE-FLAGS is non-nil, folder flags are not updated.") + +(luna-define-generic elmo-folder-unmark-answered (folder numbers) + "Un-mark messages as answered. +FOLDER is the ELMO folder structure. +NUMBERS is a list of message numbers to be processed.") + +(luna-define-generic elmo-folder-mark-as-answered (folder numbers) + "Mark messages as answered. +FOLDER is the ELMO folder structure. NUMBERS is a list of message numbers to be processed.") -(luna-define-generic elmo-folder-append-buffer (folder unread &optional number) +(luna-define-generic elmo-folder-append-buffer (folder &optional flag + number) "Append current buffer as a new message. FOLDER is the destination folder(ELMO folder structure). -If UNREAD is non-nil, message is appended as unread. +FLAG is the status of appended message. If optional argument NUMBER is specified, the new message number is set -(if possible).") +\(if possible\).") (luna-define-generic elmo-folder-append-messages (folder src-folder numbers - unread-marks &optional same-number) "Append messages from folder. @@ -376,7 +398,6 @@ Caller should make sure FOLDER is `writable'. (Can be checked with `elmo-folder-writable-p'). SRC-FOLDER is the source ELMO folder structure. NUMBERS is the message numbers to be appended in the SRC-FOLDER. -UNREAD-MARKS is a list of unread mark string. If second optional argument SAME-NUMBER is specified, message number is preserved (if possible).") @@ -485,6 +506,8 @@ Return newly created temporary directory name which contains temporary files.") (setq message-id (elmo-msgdb-overview-entity-get-id entity)) (setq number (elmo-msgdb-overview-entity-get-number entity)) (setq cache-file (elmo-file-cache-get message-id)) + (setq ignore-cache (or ignore-cache + (null (elmo-message-use-cache-p folder number)))) (if (or ignore-cache (null (elmo-file-cache-status cache-file))) ;; No cache or ignore-cache. @@ -519,14 +542,6 @@ Return newly created temporary directory name which contains temporary files.") ((folder elmo-folder) &optional visible-only) t) -(luna-define-method elmo-folder-list-unreads-internal - ((folder elmo-folder) unread-marks &optional mark-alist) - t) - -(luna-define-method elmo-folder-list-importants-internal - ((folder elmo-folder) important-mark) - t) - (defun elmo-folder-encache (folder numbers &optional unread) "Encache messages in the FOLDER with NUMBERS. If UNREAD is non-nil, messages are not marked as read." @@ -601,9 +616,7 @@ FIELD is a symbol of the field name.") (luna-define-generic elmo-message-folder (folder number) "Get primitive folder of the message.") -(luna-define-generic elmo-folder-process-crosspost (folder - &optional - number-alist) +(luna-define-generic elmo-folder-process-crosspost (folder) "Process crosspost for FOLDER. If NUMBER-ALIST is set, it is used as number-alist. Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") @@ -614,6 +627,22 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (luna-define-generic elmo-folder-newsgroups (folder) "Return list of newsgroup name of FOLDER.") +(luna-define-generic elmo-folder-search-requires-msgdb-p (folder condition) + "Return non-nil if searching in FOLDER by CONDITION requires msgdb fetch.") + +(defun elmo-folder-search-requires-msgdb-p-internal (folder condition) + (if (listp condition) + (or (elmo-folder-search-requires-msgdb-p-internal + folder (nth 1 condition)) + (elmo-folder-search-requires-msgdb-p-internal + folder (nth 2 condition))) + (and (not (string= (elmo-filter-key condition) "last")) + (not (string= (elmo-filter-key condition) "first"))))) + +(luna-define-method elmo-folder-search-requires-msgdb-p ((folder elmo-folder) + condition) + (elmo-folder-search-requires-msgdb-p-internal folder condition)) + (luna-define-method elmo-folder-newsgroups ((folder elmo-folder)) nil) @@ -623,8 +652,7 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (defun elmo-generic-folder-open (folder load-msgdb) (let ((inhibit-quit t)) - (if load-msgdb - (elmo-folder-set-msgdb-internal folder (elmo-msgdb-load folder))) + (if load-msgdb (elmo-folder-msgdb folder)) (elmo-folder-set-killed-list-internal folder (elmo-msgdb-killed-list-load (elmo-folder-msgdb-path folder)))) @@ -651,8 +679,7 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (elmo-msgdb-get-number-alist (elmo-folder-msgdb folder))) (elmo-folder-set-info-max-by-numdb folder - (elmo-msgdb-get-number-alist - (elmo-folder-msgdb folder))) + (elmo-folder-list-messages folder nil 'in-msgdb)) (elmo-folder-set-message-modified-internal folder nil) (elmo-msgdb-killed-list-save (elmo-folder-msgdb-path folder) @@ -690,13 +717,16 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (elmo-folder-persistent-internal folder)) (luna-define-method elmo-folder-creatable-p ((folder elmo-folder)) - t) ; default is creatable. + nil) ; default is not creatable. (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)) + (when (yes-or-no-p (format "Delete msgdb of \"%s\"? " + (elmo-folder-name-internal folder))) + (elmo-msgdb-delete-path folder) + t)) (luna-define-method elmo-folder-rename ((folder elmo-folder) new-name) (let* ((new-folder (elmo-make-folder new-name))) @@ -710,54 +740,83 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (elmo-msgdb-rename-path folder new-folder))) (defsubst elmo-folder-search-fast (folder condition numbers) - (when (and numbers - (vectorp condition) - (member (elmo-filter-key condition) '("first" "last"))) - (let ((len (length numbers)) - (lastp (string= (elmo-filter-key condition) "last")) - (value (string-to-number (elmo-filter-value condition)))) - (when (eq (elmo-filter-type condition) 'unmatch) - (setq lastp (not lastp) - value (- len value))) - (if lastp - (nthcdr (max (- len value) 0) numbers) - (when (> value 0) - (let ((last (nthcdr (1- value) numbers))) - (when last - (setcdr last nil)) - numbers)))))) + "Search and return list of message numbers. +Return t if CONDITION is not treated. +FOLDER is the ELMO folder structure. +CONDITION is a condition structure for searching. +NUMBERS is a list of message numbers, messages are searched from the list." + (if (and numbers + (vectorp condition)) + (cond + ((string= (elmo-filter-key condition) "flag") + (let ((msgdb (elmo-folder-msgdb folder))) + ;; msgdb should be synchronized at this point. + (cond + ((string= (elmo-filter-value condition) "unread") + (elmo-folder-list-unreads folder)) + ((string= (elmo-filter-value condition) "important") + (elmo-folder-list-importants folder)) + ((string= (elmo-filter-value condition) "answered") + (elmo-folder-list-answereds folder)) + ((string= (elmo-filter-value condition) "digest") + (nconc (elmo-folder-list-unreads folder) + (elmo-folder-list-importants folder))) + ((string= (elmo-filter-value condition) "any") + (nconc (elmo-folder-list-unreads folder) + (elmo-folder-list-importants folder) + (elmo-folder-list-answereds folder)))))) + ((member (elmo-filter-key condition) '("first" "last")) + (let ((len (length numbers)) + (lastp (string= (elmo-filter-key condition) "last")) + (value (string-to-number (elmo-filter-value condition)))) + (when (eq (elmo-filter-type condition) 'unmatch) + (setq lastp (not lastp) + value (- len value))) + (if lastp + (nthcdr (max (- len value) 0) numbers) + (when (> value 0) + (let* ((numbers (copy-sequence numbers)) + (last (nthcdr (1- value) numbers))) + (when last + (setcdr last nil)) + numbers))))) + (t + t)) + t)) (luna-define-method elmo-folder-search ((folder elmo-folder) condition &optional numbers) - (let ((numbers (or numbers (elmo-folder-list-messages folder)))) - (or (elmo-folder-search-fast folder condition numbers) - (let ((msgdb (elmo-folder-msgdb folder)) - (len (length numbers)) - matched) - (when (> len elmo-display-progress-threshold) - (elmo-progress-set 'elmo-folder-search len "Searching...")) - (unwind-protect - (dolist (number numbers) - (let ((entity (elmo-msgdb-overview-get-entity number msgdb)) - result) - (if entity - (setq result (elmo-msgdb-match-condition - condition - entity - numbers)) - (setq result condition)) - (when (elmo-filter-condition-p result) - (setq result (elmo-message-match-condition - folder - number - condition - numbers))) - (when result - (setq matched (cons number matched)))) - (elmo-progress-notify 'elmo-folder-search)) - (elmo-progress-clear 'elmo-folder-search)) - (nreverse matched))))) + (let ((numbers (or numbers (elmo-folder-list-messages folder))) + results) + (if (listp (setq results (elmo-folder-search-fast folder + condition + numbers))) + results + (let ((msgdb (elmo-folder-msgdb folder)) + (len (length numbers)) + matched) + (when (> len elmo-display-progress-threshold) + (elmo-progress-set 'elmo-folder-search len "Searching...")) + (unwind-protect + (dolist (number numbers) + (let (result) + (setq result (elmo-msgdb-match-condition + msgdb + condition + number + numbers)) + (when (elmo-filter-condition-p result) + (setq result (elmo-message-match-condition + folder + number + condition + numbers))) + (when result + (setq matched (cons number matched)))) + (elmo-progress-notify 'elmo-folder-search)) + (elmo-progress-clear 'elmo-folder-search)) + (nreverse matched))))) (luna-define-method elmo-message-match-condition ((folder elmo-folder) number condition @@ -824,12 +883,12 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (list new unread numbers max) elmo-folder-info-hashtb))) -(defun elmo-folder-set-info-max-by-numdb (folder msgdb-number) +(defun elmo-folder-set-info-max-by-numdb (folder numbers) "Set FOLDER info by MSGDB-NUMBER in msgdb." - (let ((num-db (sort (mapcar 'car msgdb-number) '<))) + (let ((numbers (sort numbers '<))) (elmo-folder-set-info-hashtb folder - (or (nth (max 0 (1- (length num-db))) num-db) 0) + (or (nth (max 0 (1- (length numbers))) numbers) 0) nil ;;(length num-db) ))) @@ -883,10 +942,7 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") append-list delete-list diff) (cons (if (equal in-folder in-db) 0 - (setq diff (elmo-list-diff - in-folder in-db - nil - )) + (setq diff (elmo-list-diff in-folder in-db nil)) (setq append-list (car diff)) (setq delete-list (cadr diff)) (if append-list @@ -896,11 +952,10 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") 0))) (length in-folder)))) -(luna-define-method elmo-folder-diff ((folder elmo-folder) - &optional numbers) - (elmo-generic-folder-diff folder numbers)) +(luna-define-method elmo-folder-diff ((folder elmo-folder)) + (elmo-generic-folder-diff folder)) -(defun elmo-generic-folder-diff (folder numbers) +(defun elmo-generic-folder-diff (folder) (if (elmo-string-match-member (elmo-folder-name-internal folder) elmo-strict-diff-folder-list) (elmo-strict-folder-diff folder) @@ -909,27 +964,20 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (in-db t) unsync messages in-db-max) - (if numbers - (setq in-db-max (or (nth (max 0 (1- (length numbers))) numbers) - 0)) - (if (not cached-in-db-max) - (let ((number-list (mapcar 'car - (elmo-msgdb-number-load - (elmo-folder-msgdb-path folder))))) - ;; No info-cache. - (setq in-db (sort number-list '<)) - (setq in-db-max (or (nth (max 0 (1- (length in-db))) in-db) - 0)) - (elmo-folder-set-info-hashtb folder in-db-max nil)) - (setq in-db-max cached-in-db-max))) - (setq unsync (if (and in-db - (car in-folder)) + (if (not cached-in-db-max) + (let ((number-list (elmo-folder-list-messages folder + nil 'in-msgdb))) + ;; No info-cache. + (setq in-db (sort number-list '<)) + (setq in-db-max (or (nth (max 0 (1- (length in-db))) in-db) + 0)) + (elmo-folder-set-info-hashtb folder in-db-max nil)) + (setq in-db-max cached-in-db-max)) + (setq unsync (if (and in-db (car in-folder)) (- (car in-folder) in-db-max) - (if (and in-folder - (null in-db)) + (if (and in-folder (null in-db)) (cdr in-folder) - (if (null (car in-folder)) - nil)))) + (car in-folder)))) (setq messages (cdr in-folder)) (if (and unsync messages (> unsync messages)) (setq unsync messages)) @@ -953,24 +1001,36 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (luna-define-method elmo-folder-append-messages ((folder elmo-folder) src-folder numbers - unread-marks &optional same-number) (elmo-generic-folder-append-messages folder src-folder numbers - unread-marks same-number)) + same-number)) (defun elmo-generic-folder-append-messages (folder src-folder numbers - unread-marks same-number) - (let (unseen seen-list succeed-numbers failure cache) + same-number) + (let ((src-msgdb-exists (not (zerop (elmo-folder-length src-folder)))) + unseen table flag mark + succeed-numbers failure cache id) + (setq table (elmo-flag-table-load (elmo-folder-msgdb-path folder))) (with-temp-buffer (set-buffer-multibyte nil) (while numbers - (setq failure nil) + (setq failure nil + id (and src-msgdb-exists + (elmo-message-field src-folder (car numbers) + 'message-id)) + mark (and src-msgdb-exists + (elmo-message-mark src-folder (car numbers))) + flag (and id + (cond + ((null mark) 'read) + ((member mark (elmo-msgdb-answered-marks)) + 'answered) + ;; + ((not (member mark (elmo-msgdb-unread-marks))) + 'read)))) (condition-case nil - (setq cache (elmo-file-cache-get - (elmo-message-field src-folder - (car numbers) - 'message-id)) + (setq cache (elmo-file-cache-get id) failure (not (and @@ -992,26 +1052,18 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (> (buffer-size) 0) (elmo-folder-append-buffer folder - (setq unseen (member (elmo-message-mark - src-folder (car numbers)) - unread-marks)) + flag (if same-number (car numbers)))))) (error (setq failure t))) ;; FETCH & APPEND finished (unless failure - (unless unseen - (setq seen-list (cons (elmo-message-field - src-folder (car numbers) - 'message-id) - seen-list))) + (when id + (elmo-flag-table-set table id flag)) (setq succeed-numbers (cons (car numbers) succeed-numbers))) (elmo-progress-notify 'elmo-folder-move-messages) (setq numbers (cdr numbers))) - (if (and seen-list (elmo-folder-persistent-p folder)) - (elmo-msgdb-seen-save (elmo-folder-msgdb-path folder) - (nconc (elmo-msgdb-seen-load - (elmo-folder-msgdb-path folder)) - seen-list))) + (when (elmo-folder-persistent-p folder) + (elmo-flag-table-save (elmo-folder-msgdb-path folder) table)) succeed-numbers))) ;; Arguments should be reduced. @@ -1020,7 +1072,6 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") no-delete-info no-delete same-number - unread-marks save-unread) (save-excursion (let* ((messages msgs) @@ -1038,39 +1089,22 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") (unless (setq succeeds (elmo-folder-append-messages dst-folder src-folder messages - unread-marks same-number)) (error "move: append message to %s failed" (elmo-folder-name-internal dst-folder))) - (elmo-folder-close dst-folder)) - (when (and (elmo-folder-persistent-p dst-folder) - save-unread) - ;; Save to seen list. - (let* ((dir (elmo-folder-msgdb-path dst-folder)) - (seen-list (elmo-msgdb-seen-load dir))) - (setq seen-list - (elmo-msgdb-add-msgs-to-seen-list - msgs (elmo-folder-msgdb src-folder) - unread-marks seen-list)) - (elmo-msgdb-seen-save dir seen-list)))) + (elmo-folder-close dst-folder))) (if (and (not no-delete) succeeds) (progn - (if (not no-delete-info) - (message "Cleaning up src folder...")) (if (and (elmo-folder-delete-messages src-folder succeeds) - (elmo-msgdb-delete-msgs - (elmo-folder-msgdb src-folder) succeeds)) + (elmo-folder-detach-messages src-folder succeeds)) (setq result t) (message "move: delete messages from %s failed." (elmo-folder-name-internal src-folder)) (setq result nil)) - (if (and result - (not no-delete-info)) - (message "Cleaning up src folder...done")) result) (if no-delete (progn - (message "Copying messages...done") + ;; (message "Copying messages...done") t) (if (eq len 0) (message "No message was moved.") @@ -1085,54 +1119,147 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).") folder (elmo-folder-expand-msgdb-path folder)))) -(defun elmo-message-mark (folder number) +(defun elmo-message-accessible-p (folder number) + "Get accessibility of the message. +Return non-nil when message is accessible." + (or (elmo-folder-plugged-p folder) + (elmo-folder-local-p folder) + (elmo-msgdb-get-cached (elmo-folder-msgdb folder) number))) + +(luna-define-generic elmo-message-set-cached (folder number cached) + "Set cache status of the message in the msgdb. +FOLDER is the ELMO folder structure. +NUMBER is a number of the message. +If CACHED is t, message is set as cached.") + +(luna-define-method elmo-message-set-cached ((folder elmo-folder) + number cached) + (when (elmo-msgdb-set-cached (elmo-folder-msgdb folder) + number + cached + (elmo-message-use-cache-p folder number)) + (elmo-folder-set-mark-modified-internal folder t))) + +(defun elmo-message-copy-entity (entity) + ;; + (elmo-msgdb-copy-overview-entity entity)) + +(defun elmo-message-entity-set-number (entity number) + (elmo-msgdb-overview-entity-set-number entity number)) + +(luna-define-generic elmo-message-entity (folder key) + "Return the message-entity structure which matches to the KEY. +KEY is a number or a string. +A number is for message number in the FOLDER. +A string is for message-id of the message.") + +(luna-define-method elmo-message-entity ((folder elmo-folder) key) + (elmo-msgdb-message-entity (elmo-folder-msgdb folder) key)) + +(luna-define-generic elmo-message-entity-parent (folder entity) + "Return the parent message-entity structure in the FOLDER. +ENTITY is the message-entity to get the parent.") + +(luna-define-method elmo-message-entity-parent ((folder elmo-folder) entity) + (elmo-msgdb-get-parent-entity entity (elmo-folder-msgdb folder))) + +(put 'elmo-folder-do-each-message-entity 'lisp-indent-function '1) +(def-edebug-spec elmo-folder-do-each-message-entity + ((symbolp form &rest form) &rest form)) + +(defsubst elmo-folder-list-message-entities (folder) + ;; List all message entities in the FOLDER. + (mapcar + (lambda (number) (elmo-message-entity folder number)) + (elmo-folder-list-messages folder t t))) + +(defmacro elmo-folder-do-each-message-entity (spec &rest form) + "Iterator for message entity in the folder. +\(elmo-folder-do-each-message-entity \(entity folder\) + ... do the process using entity... +\)" + `(dolist (,(car spec) (elmo-folder-list-message-entities ,(car (cdr spec)))) + ,@form)) + +(defmacro elmo-message-entity-number (entity) + `(elmo-msgdb-overview-entity-get-number ,entity)) + +(defun elmo-message-entity-field (entity field &optional decode) + "Get message entity field value. +ENTITY is the message entity structure obtained by `elmo-message-entity'. +FIELD is the symbol of the field name. +if optional DECODE is non-nil, returned value is decoded." + (elmo-msgdb-message-entity-field entity field decode)) + +(defun elmo-message-entity-set-field (entity field value) + "Set message entity field value. +ENTITY is the message entity structure. +FIELD is the symbol of the field name. +VALUE is the field value (raw)." + (elmo-msgdb-message-entity-set-field entity field value)) + +(luna-define-generic elmo-folder-count-flags (folder) + "Count flagged message number in the msgdb of the FOLDER. +Return a list of numbers (`new' `unread' `answered')") + +(luna-define-method elmo-folder-count-flags ((folder elmo-folder)) + (let ((new 0) + (unreads 0) + (answered 0)) + (dolist (elem (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder))) + (cond + ((string= (cadr elem) elmo-msgdb-new-mark) + (incf new)) + ((member (cadr elem) (elmo-msgdb-unread-marks)) + (incf unreads)) + ((member (cadr elem) (elmo-msgdb-answered-marks)) + (incf answered)))) + (list new unreads answered))) + +(defun elmo-message-set-flag (folder number flag) + "Set message flag. +FOLDER is a ELMO folder structure. +NUMBER is a message number to set flag. + +FLAG is a symbol which is one of the following: + `unread' (set the message as unread) + `answered' (set the message as answered) + `important' (set the message as important) +'sugar' flag: + `read' (remove new and unread flags)") + +(defun elmo-message-unset-flag (folder number flag) + "Unset message flag. +FOLDER is a ELMO folder structure. +NUMBER is a message number to set flag. + +FLAG is a symbol which is one of the following: + `unread' (remove unread and new flag) + `answered' (remove answered flag) + `important' (remove important flag) +'sugar' flag: + `read' (set unread flag)") + +(luna-define-generic elmo-message-mark (folder number) "Get mark of the message. FOLDER is the ELMO folder structure. -NUMBER is a number of the message." - (cadr (assq number (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder))))) - -(defun elmo-folder-list-messages-mark-match (folder mark-regexp) - "List messages in the FOLDER which have a mark that matches MARK-REGEXP" - (let ((case-fold-search nil) - matched) - (if mark-regexp - (dolist (elem (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder))) - (if (string-match mark-regexp (cadr elem)) - (setq matched (cons (car elem) matched))))) - matched)) - -(defun elmo-message-field (folder number field) +NUMBER is a number of the message.") + +(luna-define-method elmo-message-mark ((folder elmo-folder) number) + (when (zerop (elmo-folder-length folder)) + (error "Cannot treat this folder correctly.")) + (elmo-msgdb-get-mark (elmo-folder-msgdb folder) number)) + +(luna-define-generic elmo-message-field (folder number field) "Get message field value in the msgdb. FOLDER is the ELMO folder structure. NUMBER is a number of the message. -FIELD is a symbol of the field." - (case field - (message-id (elmo-msgdb-overview-entity-get-id - (elmo-msgdb-overview-get-entity - number (elmo-folder-msgdb folder)))) - (subject (elmo-msgdb-overview-entity-get-subject - (elmo-msgdb-overview-get-entity - number (elmo-folder-msgdb folder)))) - (size (elmo-msgdb-overview-entity-get-size - (elmo-msgdb-overview-get-entity - number (elmo-folder-msgdb folder)))) - (date (elmo-msgdb-overview-entity-get-date - (elmo-msgdb-overview-get-entity - number (elmo-folder-msgdb folder)))) - (to (elmo-msgdb-overview-entity-get-to - (elmo-msgdb-overview-get-entity - number (elmo-folder-msgdb folder)))) - (cc (elmo-msgdb-overview-entity-get-cc - (elmo-msgdb-overview-get-entity - number (elmo-folder-msgdb folder)))))) - -(defun elmo-message-set-mark (folder number mark) - "Set mark for the message in the FOLDER with NUMBER as MARK." - (elmo-msgdb-set-mark-alist - (elmo-folder-msgdb folder) - (elmo-msgdb-mark-set - (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder)) - number mark))) +FIELD is a symbol of the field.") + +(luna-define-method elmo-message-field ((folder elmo-folder) number field) + (when (zerop (elmo-folder-length folder)) + (error "Cannot treat this folder correctly.")) + (elmo-msgdb-get-field (elmo-folder-msgdb folder) number field)) (luna-define-method elmo-message-use-cache-p ((folder elmo-folder) number) nil) ; default is not use cache. @@ -1140,25 +1267,71 @@ FIELD is a symbol of the field." (luna-define-method elmo-message-folder ((folder elmo-folder) number) folder) ; default is folder -(luna-define-method elmo-folder-unmark-important ((folder elmo-folder) numbers) - t) +(luna-define-method elmo-folder-unmark-important ((folder elmo-folder) + numbers + &optional ignore-flags) + (when (elmo-folder-msgdb-internal folder) + (dolist (number numbers) + (elmo-msgdb-unset-flag (elmo-folder-msgdb folder) + folder + number + 'important)))) (luna-define-method elmo-folder-mark-as-important ((folder elmo-folder) - numbers) - t) - -(luna-define-method elmo-folder-unmark-read ((folder elmo-folder) numbers) - t) - -(luna-define-method elmo-folder-mark-as-read ((folder elmo-folder) numbers) - t) - -(luna-define-method elmo-folder-process-crosspost ((folder elmo-folder) - &optional - number-alist) + numbers + &optional ignore-flags) + (when (elmo-folder-msgdb-internal folder) + (dolist (number numbers) + (elmo-msgdb-set-flag (elmo-folder-msgdb folder) + folder + number + 'important)))) + +(luna-define-method elmo-folder-unmark-read ((folder elmo-folder) + numbers + &optional ignore-flags) + (when (elmo-folder-msgdb-internal folder) + (dolist (number numbers) + (elmo-msgdb-unset-flag (elmo-folder-msgdb folder) + folder + number + 'read)))) + +(luna-define-method elmo-folder-mark-as-read ((folder elmo-folder) + numbers + &optional ignore-flag) + (when (elmo-folder-msgdb-internal folder) + (dolist (number numbers) + (elmo-msgdb-set-flag (elmo-folder-msgdb folder) + folder + number + 'read)))) + +(luna-define-method elmo-folder-unmark-answered ((folder elmo-folder) numbers) + (when (elmo-folder-msgdb-internal folder) + (dolist (number numbers) + (elmo-msgdb-unset-flag (elmo-folder-msgdb folder) + folder + number + 'answered)))) + +(luna-define-method elmo-folder-mark-as-answered ((folder elmo-folder) numbers) + (when (elmo-folder-msgdb-internal folder) + (dolist (number numbers) + (elmo-msgdb-set-flag (elmo-folder-msgdb folder) + folder + number + 'answered)))) + +(luna-define-method elmo-folder-process-crosspost ((folder elmo-folder)) ;; Do nothing. ) +;;(luna-define-generic elmo-folder-append-message-entity (folder entity +;; &optional +;; flag-table) +;; "Append ENTITY to the folder.") + (defun elmo-generic-folder-append-msgdb (folder append-msgdb) (if append-msgdb (let* ((number-alist (elmo-msgdb-get-number-alist append-msgdb)) @@ -1170,6 +1343,10 @@ FIELD is a symbol of the field." pair overview to-be-deleted mark-alist) + (elmo-folder-set-msgdb-internal folder + (elmo-msgdb-append + (elmo-folder-msgdb folder) + append-msgdb)) (while cur (setq all-alist (delq (car cur) all-alist)) ;; same message id exists. @@ -1195,10 +1372,6 @@ FIELD is a symbol of the field." (t ;; Do nothing. (setq to-be-deleted nil))) - (elmo-folder-set-msgdb-internal folder - (elmo-msgdb-append - (elmo-folder-msgdb folder) - append-msgdb t)) (length to-be-deleted)) 0)) @@ -1284,78 +1457,69 @@ FIELD is a symbol of the field." (or result (and err (signal (car err) (cdr err)))))) +(defun elmo-folder-kill-messages-before (folder msg) + (elmo-folder-set-killed-list-internal + folder + (list (cons 1 msg)))) + +(defun elmo-folder-kill-messages (folder numbers) + "Kill(hide) messages in the FOLDER with NUMBERS." + (elmo-folder-set-killed-list-internal + folder + (elmo-number-set-append-list (elmo-folder-killed-list-internal + folder) numbers))) + + (luna-define-method elmo-folder-clear ((folder elmo-folder) &optional keep-killed) (unless keep-killed (elmo-folder-set-killed-list-internal folder nil)) (elmo-folder-set-msgdb-internal folder (elmo-msgdb-clear))) -(defun elmo-folder-synchronize (folder - new-mark ;"N" - unread-uncached-mark ;"U" - unread-cached-mark ;"!" - read-uncached-mark ;"u" - important-mark ;"$" - &optional ignore-msgdb - no-check) +(luna-define-generic elmo-folder-synchronize (folder + &optional ignore-msgdb + no-check) "Synchronize the folder data to the newest status. FOLDER is the ELMO folder structure. -NEW-MARK, UNREAD-CACHED-MARK, READ-UNCACHED-MARK, and IMPORTANT-MARK -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 +flag status. If IGNORE-MSGDB is 'visible-only, only visible messages \(the messages which are not in the killed-list\) are thrown away and synchronized. If NO-CHECK is non-nil, rechecking folder is skipped. +Return a list of a cross-posted message number. +If update process is interrupted, return nil.") -Return a list of -\(NEW-MSGDB DELETE-LIST CROSSED\) -NEW-MSGDB is the newly appended msgdb. -DELETE-LIST is a list of deleted message number. -CROSSED is cross-posted message number. -If update process is interrupted, return nil." +(luna-define-method elmo-folder-synchronize ((folder elmo-folder) + &optional ignore-msgdb no-check) (let ((killed-list (elmo-folder-killed-list-internal folder)) (before-append t) - number-alist mark-alist + number-alist old-msgdb diff diff-2 delete-list new-list new-msgdb mark - seen-list crossed after-append) + flag-table crossed after-append numbers) (setq old-msgdb (elmo-folder-msgdb folder)) - ;; Load seen-list. - (setq seen-list (elmo-msgdb-seen-load (elmo-folder-msgdb-path folder))) - (setq number-alist (elmo-msgdb-get-number-alist - (elmo-folder-msgdb folder))) - (setq mark-alist (elmo-msgdb-get-mark-alist - (elmo-folder-msgdb folder))) - (if ignore-msgdb - (progn - (setq seen-list (nconc - (elmo-msgdb-mark-alist-to-seen-list - number-alist mark-alist - (concat important-mark read-uncached-mark)) - seen-list)) - (elmo-folder-clear folder (eq ignore-msgdb 'visible-only)))) + (setq flag-table (elmo-flag-table-load (elmo-folder-msgdb-path folder))) + (when ignore-msgdb + (elmo-msgdb-flag-table (elmo-folder-msgdb folder) flag-table) + (elmo-folder-clear folder (eq ignore-msgdb 'visible-only))) + (setq numbers (sort (elmo-folder-list-messages folder nil t) '<)) (unless no-check (elmo-folder-check folder)) (condition-case nil (progn (message "Checking folder diff...") - ;; TODO: killed list is loaded in elmo-folder-open and - ;; list-messages use internal killed-list-folder. (setq diff (elmo-list-diff (elmo-folder-list-messages folder (eq 'visible-only ignore-msgdb)) - (unless ignore-msgdb - (sort (mapcar - 'car - number-alist) - '<)))) + numbers)) (message "Checking folder diff...done") (setq new-list (elmo-folder-confirm-appends (car diff))) - ;; Set killed list. + ;; Set killed list as ((1 . MAX-OF-DISAPPEARED)) (when (and (not (eq (length (car diff)) (length new-list))) (setq diff-2 (elmo-list-diff (car diff) new-list))) - (elmo-msgdb-append-to-killed-list folder (car diff-2))) + (elmo-folder-kill-messages-before folder + (nth (- (length (car diff-2)) 1) + (car diff-2)))) (setq delete-list (cadr diff)) (if (or (equal diff '(nil nil)) (equal diff '(nil)) @@ -1364,23 +1528,20 @@ If update process is interrupted, return nil." (progn (elmo-folder-update-number folder) (elmo-folder-process-crosspost folder) - (list nil nil nil) ; no updates. + 0 ; no updates. ) - (if delete-list (elmo-msgdb-delete-msgs - (elmo-folder-msgdb folder) delete-list)) + (when delete-list + (elmo-folder-detach-messages folder delete-list)) (when new-list - (setq new-msgdb (elmo-folder-msgdb-create - folder - new-list - new-mark unread-cached-mark - read-uncached-mark important-mark - seen-list)) (elmo-msgdb-change-mark (elmo-folder-msgdb folder) - new-mark unread-uncached-mark) - ;; Clear seen-list. + elmo-msgdb-new-mark + elmo-msgdb-unread-uncached-mark) + (setq new-msgdb (elmo-folder-msgdb-create + folder new-list flag-table)) + ;; Clear flag-table (if (elmo-folder-persistent-p folder) - (setq seen-list (elmo-msgdb-seen-save - (elmo-folder-msgdb-path folder) nil))) + (elmo-flag-table-save (elmo-folder-msgdb-path folder) + nil)) (setq before-append nil) (setq crossed (elmo-folder-append-msgdb folder new-msgdb)) ;; process crosspost. @@ -1389,32 +1550,39 @@ If update process is interrupted, return nil." (elmo-folder-set-message-modified-internal folder t) (elmo-folder-set-mark-modified-internal folder t)) ;; return value. - (list new-msgdb delete-list crossed))) + (or crossed 0))) (quit ;; Resume to the original status. - (if before-append - (elmo-folder-set-msgdb-internal folder old-msgdb)) + (if before-append (elmo-folder-set-msgdb-internal folder old-msgdb)) (elmo-folder-set-killed-list-internal folder killed-list) nil)))) -(defun elmo-folder-messages (folder) - "Return number of messages in the FOLDER." - (length - (elmo-msgdb-get-number-alist - (elmo-folder-msgdb folder)))) - -;;; -(defun elmo-msgdb-load (folder) - (message "Loading msgdb for %s..." (elmo-folder-name-internal folder)) - (let* ((path (elmo-folder-msgdb-path folder)) - (overview (elmo-msgdb-overview-load path)) - (msgdb (list overview - (elmo-msgdb-number-load path) - (elmo-msgdb-mark-load path) - (elmo-msgdb-make-overview-hashtb overview)))) - (message "Loading msgdb for %s...done" (elmo-folder-name-internal folder)) - (elmo-folder-set-info-max-by-numdb folder - (elmo-msgdb-get-number-alist msgdb)) +(luna-define-generic elmo-folder-detach-messages (folder numbers) + "Remove messages with NUMBERS from MSGDB.") + +(luna-define-method elmo-folder-detach-messages ((folder elmo-folder) + numbers) + (elmo-msgdb-delete-msgs (elmo-folder-msgdb folder) numbers)) + +(luna-define-generic elmo-folder-length (folder) + "Return number of messages in the FOLDER.") + +(luna-define-method elmo-folder-length ((folder elmo-folder)) + (if (elmo-folder-msgdb-internal folder) + (elmo-msgdb-length (elmo-folder-msgdb folder)) + 0)) + +(defun elmo-msgdb-load (folder &optional silent) + (unless silent + (message "Loading msgdb for %s..." (elmo-folder-name-internal folder))) + (let ((msgdb (elmo-load-msgdb (elmo-folder-msgdb-path folder)))) + (elmo-folder-set-info-max-by-numdb + folder + (mapcar 'elmo-msgdb-overview-entity-get-number + (elmo-msgdb-get-overview msgdb))) + (unless silent + (message "Loading msgdb for %s...done" + (elmo-folder-name-internal folder))) msgdb)) (defun elmo-msgdb-delete-path (folder) @@ -1503,6 +1671,11 @@ Return a hashtable for newsgroups." (funcall func nil))) (setq types (cdr types))))) +(luna-define-method elmo-folder-rename-internal ((folder elmo-folder) + new-folder) + (error "Cannot rename %s folder" + (symbol-name (elmo-folder-type-internal folder)))) + ;;; Define folders. (elmo-define-folder ?% 'imap4) @@ -1530,12 +1703,16 @@ Return a hashtable for newsgroups." 'elmo-imap4-default-user) (elmo-define-obsolete-variable 'elmo-default-imap4-port 'elmo-imap4-default-port) +(elmo-define-obsolete-variable 'elmo-default-imap4-stream-type + 'elmo-imap4-default-stream-type) (elmo-define-obsolete-variable 'elmo-default-nntp-server 'elmo-nntp-default-server) (elmo-define-obsolete-variable 'elmo-default-nntp-user 'elmo-nntp-default-user) (elmo-define-obsolete-variable 'elmo-default-nntp-port 'elmo-nntp-default-port) +(elmo-define-obsolete-variable 'elmo-default-nntp-stream-type + 'elmo-nntp-default-stream-type) (elmo-define-obsolete-variable 'elmo-default-pop3-server 'elmo-pop3-default-server) (elmo-define-obsolete-variable 'elmo-default-pop3-user @@ -1544,6 +1721,8 @@ 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-default-pop3-stream-type + 'elmo-pop3-default-stream-type) (elmo-define-obsolete-variable 'elmo-cache-dirname 'elmo-cache-directory) (elmo-define-obsolete-variable 'elmo-msgdb-dir @@ -1558,6 +1737,7 @@ Return a hashtable for newsgroups." ;; autoloads (autoload 'elmo-dop-queue-flush "elmo-dop") +(autoload 'elmo-nntp-post "elmo-nntp") (require 'product) (product-provide (provide 'elmo) (require 'elmo-version))