;;; -*-Scheme-*-
;;;
-;;; $Id: imail-core.scm,v 1.112 2000/06/30 17:21:24 cph Exp $
+;;; $Id: imail-core.scm,v 1.113 2000/08/05 01:53:36 cph Exp $
;;;
;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
;;;
(%get-message folder index))
(define-generic %get-message (folder index))
-\f
+
;; -------------------------------------------------------------------
;; Remove all messages in FOLDER that are marked for deletion.
;; Unspecified result.
;; may be a string. Returns a list of messages.
(define-generic search-folder (folder criteria))
-
+\f
;; -------------------------------------------------------------------
;; Compare FOLDER's cache with the persistent folder and return a
;; symbol indicating whether they are synchronized, as follows:
;; Return #T if FOLDER supports MIME parsing.
(define-generic folder-supports-mime? (folder))
+
+;; -------------------------------------------------------------------
+;; Preload outline information about each message in the folder.
+;; Normally used prior to generating a folder summary, to accelerate
+;; the downloading of this information from the server. This
+;; operation need not be implemented, as it is just a performance
+;; enhancement.
+
+(define-generic preload-folder-outlines (folder))
\f
;;;; Message type
;;; -*-Scheme-*-
;;;
-;;; $Id: imail-imap.scm,v 1.142 2000/08/02 13:15:27 cph Exp $
+;;; $Id: imail-imap.scm,v 1.143 2000/08/05 01:53:44 cph Exp $
;;;
;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
;;;
(guarantee-slot-initialized message initpred "body structure"
'(BODYSTRUCTURE)))))
\f
+(define-method preload-folder-outlines ((folder <imap-folder>))
+ (guarantee-imap-folder-open folder)
+ (let ((messages
+ (messages-satisfying folder
+ (lambda (message)
+ (not (and (imap-message-header-fields-initialized? message)
+ (imap-message-length-initialized? message)))))))
+ (if (pair? messages)
+ ((imail-ui:message-wrapper "Reading message headers")
+ (lambda ()
+ (imap:command:fetch-set (imap-folder-connection folder)
+ (message-list->set messages)
+ '(RFC822.HEADER RFC822.SIZE)))))))
+
+
+(define imap-message-header-fields-initialized?
+ (slot-initpred <imap-message> 'HEADER-FIELDS))
+
+(define imap-message-length-initialized?
+ (slot-initpred <imap-message> 'LENGTH))
+
+(define (messages-satisfying folder predicate)
+ (let ((n (folder-length folder)))
+ (let loop ((i 0) (messages '()))
+ (if (< i n)
+ (loop (+ i 1)
+ (let ((message (get-message folder i)))
+ (if (predicate message)
+ (cons message messages)
+ messages)))
+ (reverse! messages)))))
+
+(define (message-list->set messages)
+ (let loop ((indexes (map message-index messages)) (groups '()))
+ (if (pair? indexes)
+ (let ((start (car indexes)))
+ (let parse-group ((this start) (rest (cdr indexes)))
+ (if (and (pair? rest) (= (car rest) (+ this 1)))
+ (parse-group (car rest) (cdr rest))
+ (loop rest
+ (cons (if (= start this)
+ (number->string (+ start 1))
+ (string-append (number->string (+ start 1))
+ ":"
+ (number->string (+ this 1))))
+ groups)))))
+ (decorated-string-append "" "," "" (reverse! groups)))))
+\f
;;;; MIME support
(define-method mime-message-body-structure ((message <imap-message>))
uid items))
(define (imap:command:fetch-range connection start end items)
- (imap:command:multiple-response
- imap:response:fetch? connection
- 'FETCH
- `',(string-append (number->string (+ start 1))
- ":"
- (if end (number->string end) "*"))
- items))
+ (imap:command:fetch-set connection
+ (string-append (number->string (+ start 1))
+ ":"
+ (if end (number->string end) "*"))
+ items))
+
+(define (imap:command:fetch-set connection set items)
+ (imap:command:multiple-response imap:response:fetch? connection
+ 'FETCH `',set items))
\f
(define (imap:command:uid-store-flags connection uid flags)
(imap:command:no-response connection 'UID 'STORE uid 'FLAGS flags))