* elmo-imap4.el (elmo-imap4-send-command):
[elisp/wanderlust.git] / elmo / elmo-internal.el
1 ;;; elmo-internal.el -- Internal Interface for ELMO.
2
3 ;; Copyright 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
4
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Keywords: mail, net news
7
8 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24 ;;
25
26 ;;; Commentary:
27 ;; 
28
29 ;;; Code:
30 ;; 
31 (require 'elmo-localdir)
32
33 (defsubst elmo-internal-list-folder-subr (spec &optional nonsort)
34   (let* ((directive (nth 1 spec))
35          (arg (nth 2 spec))
36          (flist (elmo-list-folder-by-location
37                  spec
38                  (elmo-internal-list-location directive arg))))
39     (if nonsort
40         (cons (or (elmo-max-of-list flist) 0)
41               (length flist))
42       (sort flist '<))))
43
44 (defun elmo-internal-list-folder (spec)
45     (let ((killed (and elmo-use-killed-list
46                      (elmo-msgdb-killed-list-load
47                       (elmo-msgdb-expand-path nil spec))))
48         numbers)
49     (setq numbers (elmo-internal-list-folder-subr spec))
50     (if killed
51         (delq nil
52               (mapcar (lambda (number)
53                         (unless (memq number killed) number))
54                       numbers))
55       numbers)))
56
57 (defun elmo-internal-list-folder-by-location (spec location &optional msgdb)
58   (let* ((path (elmo-msgdb-expand-path nil spec))
59          (location-alist
60           (if msgdb
61               (elmo-msgdb-get-location msgdb)
62             (elmo-msgdb-location-load path)))
63          (i 0)
64          result pair
65          location-max modified)
66     (setq location-max
67           (or (elmo-max-of-list (mapcar 'car location-alist)) 0))
68     (when location-max
69       (while location
70         (if (setq pair (rassoc (car location) location-alist))
71             (setq result
72                   (append result
73                           (list (cons (car pair) (car location)))))
74           (setq i (1+ i))
75           (setq result (append result
76                                (list
77                                 (cons (+ location-max i) (car location))))))
78         (setq location (cdr location))))
79     (setq result (sort result '(lambda (x y)
80                                  (< (car x)(car y)))))
81     (if (not (equal result location-alist))
82         (setq modified t))
83     (if modified
84         (elmo-msgdb-location-save path result))
85     (mapcar 'car result)))
86
87 (defun elmo-internal-list-location (directive arg)
88   (let ((mark-alist
89          (or elmo-msgdb-global-mark-alist
90              (setq elmo-msgdb-global-mark-alist
91                    (elmo-object-load (expand-file-name
92                                       elmo-msgdb-global-mark-filename
93                                       elmo-msgdb-dir)))))
94         result)
95     (mapcar (function (lambda (x)
96                         (setq result (cons (car x) result))))
97             mark-alist)
98     (nreverse result)))
99
100 (defun elmo-internal-msgdb-create-entity (number loc-alist)
101   (elmo-localdir-msgdb-create-overview-entity-from-file
102    number
103    (elmo-cache-get-path (cdr (assq number loc-alist)))))
104
105 (defun elmo-internal-msgdb-create (spec numlist new-mark
106                                        already-mark seen-mark
107                                        important-mark
108                                        seen-list
109                                        &optional msgdb)
110   (when numlist
111     (let* ((directive (nth 1 spec))
112            (arg       (nth 2 spec))
113            (loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
114                         (elmo-msgdb-location-load (elmo-msgdb-expand-path
115                                                    nil spec))))
116            (loc-list (elmo-internal-list-location directive arg))
117            overview number-alist mark-alist entity
118            i percent num location pair)
119       (setq num (length numlist))
120       (setq i 0)
121       (message "Creating msgdb...")
122       (while numlist
123         (setq entity
124               (elmo-internal-msgdb-create-entity
125                (car numlist) loc-alist))
126         (if (null entity)
127             ()
128           (setq overview
129                 (elmo-msgdb-append-element
130                  overview entity))
131           (setq number-alist
132                 (elmo-msgdb-number-add number-alist
133                                        (elmo-msgdb-overview-entity-get-number
134                                         entity)
135                                        (elmo-msgdb-overview-entity-get-id
136                                         entity)))
137           (setq location (cdr (assq (car numlist) loc-alist)))
138           (unless (memq location seen-list)
139             (setq mark-alist
140                   (elmo-msgdb-mark-append
141                    mark-alist
142                    (elmo-msgdb-overview-entity-get-number
143                     entity)
144                                         ;(nth 0 entity)
145                    (or (elmo-msgdb-global-mark-get
146                         (elmo-msgdb-overview-entity-get-id
147                          entity))
148                        (if (elmo-cache-exists-p
149                             (elmo-msgdb-overview-entity-get-id
150                              entity))
151                            already-mark
152                          new-mark))))))
153         (when (> num elmo-display-progress-threshold)
154           (setq i (1+ i))
155           (setq percent (/ (* i 100) num))
156           (elmo-display-progress
157            'elmo-internal-msgdb-create "Creating msgdb..."
158            percent))
159         (setq numlist (cdr numlist)))
160       (message "Creating msgdb...done.")
161       (list overview number-alist mark-alist loc-alist))))
162
163 (defalias 'elmo-internal-msgdb-create-as-numlist 'elmo-internal-msgdb-create)
164
165 (defun elmo-internal-list-folders (spec &optional hierarchy)
166   ;; XXX hard cording.
167   (unless (nth 1 spec) ; toplevel.
168     (list (list "'cache") "'mark")))
169
170 (defvar elmo-internal-mark "$")
171
172 (defun elmo-internal-append-msg (spec string &optional msg no-see)
173   (elmo-set-work-buf
174    (insert string)
175    (let* ((msgid (elmo-field-body "message-id"))
176           (path (elmo-cache-get-path msgid))
177           dir)
178      (when path
179        (setq dir (directory-file-name (file-name-directory path)))
180        (if (not (file-exists-p dir))
181            (elmo-make-directory dir))
182        (as-binary-output-file (write-region (point-min) (point-max)
183                                             path nil 'no-msg)))
184      (elmo-msgdb-global-mark-set msgid elmo-internal-mark))))
185
186 (defun elmo-internal-delete-msgs (spec msgs &optional msgdb)
187   (let ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
188                      (elmo-msgdb-location-load (elmo-msgdb-expand-path
189                                                 nil spec)))))
190     (mapcar '(lambda (msg) (elmo-internal-delete-msg spec msg
191                                                      loc-alist))
192             msgs)))
193
194 (defun elmo-internal-delete-msg (spec number loc-alist)
195   (let ((pair (assq number loc-alist)))
196     (elmo-msgdb-global-mark-delete (cdr pair))))
197
198 (defun elmo-internal-read-msg (spec number outbuf &optional msgdb)
199   (save-excursion
200     (let* ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
201                         (elmo-msgdb-location-load (elmo-msgdb-expand-path
202                                                    nil spec))))
203            (file (elmo-cache-get-path (cdr (assq number loc-alist)))))
204       (set-buffer outbuf)
205       (erase-buffer)
206       (when (file-exists-p file)
207         (as-binary-input-file (insert-file-contents file))
208         (elmo-delete-cr-get-content-type)))))
209
210 (defun elmo-internal-max-of-folder (spec)
211   (elmo-internal-list-folder-subr spec t))
212
213 (defun elmo-internal-check-validity (spec)
214   nil)
215
216 (defun elmo-internal-sync-validity (spec)
217   nil)
218
219 (defun elmo-internal-folder-exists-p (spec)
220   t)
221
222 (defun elmo-internal-folder-creatable-p (spec)
223   nil)
224
225 (defun elmo-internal-create-folder (spec)
226   nil)
227
228 (defun elmo-internal-search (spec condition &optional from-msgs msgdb)
229   (let* ((mark-alist
230          (or elmo-msgdb-global-mark-alist
231              (setq elmo-msgdb-global-mark-alist
232                    (elmo-object-load (expand-file-name
233                                       elmo-msgdb-global-mark-filename
234                                       elmo-msgdb-dir)))))
235          (loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
236                       (elmo-msgdb-location-load (elmo-msgdb-expand-path
237                                                  nil spec))))
238          cache-file
239          ret-val
240          case-fold-search msg
241          percent i num)
242     (setq num (length loc-alist))
243     (setq i 0)
244     (while loc-alist
245       (if (and (setq cache-file (elmo-cache-exists-p (cdr (car loc-alist))))
246                (elmo-file-field-condition-match cache-file
247                                                 condition))
248           (setq ret-val (append ret-val (list (car (car loc-alist))))))
249       (setq i (1+ i))
250       (setq percent (/ (* i 100) num))
251       (elmo-display-progress
252        'elmo-internal-search "Searching..."
253        percent)
254       (setq loc-alist (cdr loc-alist)))
255     ret-val))
256
257 (defun elmo-internal-use-cache-p (spec number)
258   nil)
259
260 (defun elmo-internal-local-file-p (spec number)
261   nil ;; XXXX
262   )
263
264 (defalias 'elmo-internal-sync-number-alist 'elmo-generic-sync-number-alist)
265 (defalias 'elmo-internal-list-folder-unread
266   'elmo-generic-list-folder-unread)
267 (defalias 'elmo-internal-list-folder-important
268   'elmo-generic-list-folder-important)
269 (defalias 'elmo-internal-commit 'elmo-generic-commit)
270
271 (provide 'elmo-internal)
272
273 ;;; elmo-internal.el ends here