* elmo-maildir.el (elmo-maildir-pack-number): Implemented.
[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          (killed (and elmo-use-killed-list
40                       (elmo-msgdb-killed-list-load
41                        (elmo-msgdb-expand-path nil spec))))
42          numbers)
43     (if nonsort
44         (cons (or (elmo-max-of-list flist) 0)
45               (if killed
46                   (- (length flist) (length killed))
47                 (length flist)))
48       (setq numbers (sort flist '<))
49       (if killed
50           (delq nil
51                 (mapcar (lambda (number)
52                           (unless (memq number killed) number))
53                         numbers))
54         numbers))))
55
56 (defun elmo-internal-list-folder (spec)
57   (elmo-internal-list-folder-subr spec))
58
59 (defun elmo-internal-list-folder-by-location (spec location &optional msgdb)
60   (let* ((path (elmo-msgdb-expand-path nil spec))
61          (location-alist
62           (if msgdb
63               (elmo-msgdb-get-location msgdb)
64             (elmo-msgdb-location-load path)))
65          (i 0)
66          result pair
67          location-max modified)
68     (setq location-max
69           (or (elmo-max-of-list (mapcar 'car location-alist)) 0))
70     (when location-max
71       (while location
72         (if (setq pair (rassoc (car location) location-alist))
73             (setq result
74                   (append result
75                           (list (cons (car pair) (car location)))))
76           (setq i (1+ i))
77           (setq result (append result
78                                (list
79                                 (cons (+ location-max i) (car location))))))
80         (setq location (cdr location))))
81     (setq result (sort result '(lambda (x y)
82                                  (< (car x)(car y)))))
83     (if (not (equal result location-alist))
84         (setq modified t))
85     (if modified
86         (elmo-msgdb-location-save path result))
87     (mapcar 'car result)))
88
89 (defun elmo-internal-list-location (directive arg)
90   (let ((mark-alist
91          (or elmo-msgdb-global-mark-alist
92              (setq elmo-msgdb-global-mark-alist
93                    (elmo-object-load (expand-file-name
94                                       elmo-msgdb-global-mark-filename
95                                       elmo-msgdb-dir)))))
96         result)
97     (mapcar (function (lambda (x)
98                         (setq result (cons (car x) result))))
99             mark-alist)
100     (nreverse result)))
101
102 (defun elmo-internal-msgdb-create-entity (number loc-alist)
103   (elmo-localdir-msgdb-create-overview-entity-from-file
104    number
105    (elmo-cache-get-path (cdr (assq number loc-alist)))))
106
107 (defun elmo-internal-msgdb-create (spec numlist new-mark
108                                        already-mark seen-mark
109                                        important-mark
110                                        seen-list
111                                        &optional msgdb)
112   (when numlist
113     (let* ((directive (nth 1 spec))
114            (arg       (nth 2 spec))
115            (loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
116                         (elmo-msgdb-location-load (elmo-msgdb-expand-path
117                                                    nil spec))))
118            (loc-list (elmo-internal-list-location directive arg))
119            overview number-alist mark-alist entity
120            i percent num location pair)
121       (setq num (length numlist))
122       (setq i 0)
123       (message "Creating msgdb...")
124       (while numlist
125         (setq entity
126               (elmo-internal-msgdb-create-entity
127                (car numlist) loc-alist))
128         (if (null entity)
129             ()
130           (setq overview
131                 (elmo-msgdb-append-element
132                  overview entity))
133           (setq number-alist
134                 (elmo-msgdb-number-add number-alist
135                                        (elmo-msgdb-overview-entity-get-number
136                                         entity)
137                                        (elmo-msgdb-overview-entity-get-id
138                                         entity)))
139           (setq location (cdr (assq (car numlist) loc-alist)))
140           (unless (memq location seen-list)
141             (setq mark-alist
142                   (elmo-msgdb-mark-append
143                    mark-alist
144                    (elmo-msgdb-overview-entity-get-number
145                     entity)
146                                         ;(nth 0 entity)
147                    (or (elmo-msgdb-global-mark-get
148                         (elmo-msgdb-overview-entity-get-id
149                          entity))
150                        (if (elmo-cache-exists-p
151                             (elmo-msgdb-overview-entity-get-id
152                              entity))
153                            already-mark
154                          new-mark))))))
155         (when (> num elmo-display-progress-threshold)
156           (setq i (1+ i))
157           (setq percent (/ (* i 100) num))
158           (elmo-display-progress
159            'elmo-internal-msgdb-create "Creating msgdb..."
160            percent))
161         (setq numlist (cdr numlist)))
162       (message "Creating msgdb...done.")
163       (list overview number-alist mark-alist loc-alist))))
164
165 (defalias 'elmo-internal-msgdb-create-as-numlist 'elmo-internal-msgdb-create)
166
167 (defun elmo-internal-list-folders (spec &optional hierarchy)
168   ;; XXX hard cording.
169   (unless (nth 1 spec) ; toplevel.
170     (list (list "'cache") "'mark")))
171
172 (defvar elmo-internal-mark "$")
173
174 (defun elmo-internal-append-msg (spec string &optional msg no-see)
175   (elmo-set-work-buf
176    (insert string)
177    (let* ((msgid (elmo-field-body "message-id"))
178           (path (elmo-cache-get-path msgid))
179           dir)
180      (when path
181        (setq dir (directory-file-name (file-name-directory path)))
182        (if (not (file-exists-p dir))
183            (elmo-make-directory dir))
184        (as-binary-output-file (write-region (point-min) (point-max)
185                                             path nil 'no-msg)))
186      (elmo-msgdb-global-mark-set msgid elmo-internal-mark))))
187
188 (defun elmo-internal-delete-msgs (spec msgs &optional msgdb)
189   (let ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
190                      (elmo-msgdb-location-load (elmo-msgdb-expand-path
191                                                 nil spec)))))
192     (mapcar '(lambda (msg) (elmo-internal-delete-msg spec msg
193                                                      loc-alist))
194             msgs)))
195
196 (defun elmo-internal-delete-msg (spec number loc-alist)
197   (let ((pair (assq number loc-alist)))
198     (elmo-msgdb-global-mark-delete (cdr pair))))
199
200 (defun elmo-internal-read-msg (spec number outbuf &optional msgdb)
201   (save-excursion
202     (let* ((loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
203                         (elmo-msgdb-location-load (elmo-msgdb-expand-path
204                                                    nil spec))))
205            (file (elmo-cache-get-path (cdr (assq number loc-alist)))))
206       (set-buffer outbuf)
207       (erase-buffer)
208       (when (file-exists-p file)
209         (as-binary-input-file (insert-file-contents file))
210         (elmo-delete-cr-get-content-type)))))
211
212 (defun elmo-internal-max-of-folder (spec)
213   (elmo-internal-list-folder-subr spec t))
214
215 (defun elmo-internal-check-validity (spec)
216   nil)
217
218 (defun elmo-internal-sync-validity (spec)
219   nil)
220
221 (defun elmo-internal-folder-exists-p (spec)
222   t)
223
224 (defun elmo-internal-folder-creatable-p (spec)
225   nil)
226
227 (defun elmo-internal-create-folder (spec)
228   nil)
229
230 (defun elmo-internal-search (spec condition &optional from-msgs msgdb)
231   (let* ((mark-alist
232          (or elmo-msgdb-global-mark-alist
233              (setq elmo-msgdb-global-mark-alist
234                    (elmo-object-load (expand-file-name
235                                       elmo-msgdb-global-mark-filename
236                                       elmo-msgdb-dir)))))
237          (loc-alist (if msgdb (elmo-msgdb-get-location msgdb)
238                       (elmo-msgdb-location-load (elmo-msgdb-expand-path
239                                                  nil spec))))
240          (number-list (mapcar 'car loc-alist))
241          cache-file
242          ret-val
243          case-fold-search msg
244          percent i num)
245     (setq num (length loc-alist))
246     (setq i 0)
247     (while loc-alist
248       (if (and (setq cache-file (elmo-cache-exists-p (cdr (car loc-alist))))
249                (elmo-file-field-condition-match cache-file
250                                                 condition
251                                                 (car (car loc-alist))
252                                                 number-list))
253           (setq ret-val (append ret-val (list (car (car loc-alist))))))
254       (setq i (1+ i))
255       (setq percent (/ (* i 100) num))
256       (elmo-display-progress
257        'elmo-internal-search "Searching..."
258        percent)
259       (setq loc-alist (cdr loc-alist)))
260     ret-val))
261
262 (defun elmo-internal-use-cache-p (spec number)
263   nil)
264
265 (defun elmo-internal-local-file-p (spec number)
266   nil ;; XXXX
267   )
268
269 (defalias 'elmo-internal-sync-number-alist 'elmo-generic-sync-number-alist)
270 (defalias 'elmo-internal-list-folder-unread
271   'elmo-generic-list-folder-unread)
272 (defalias 'elmo-internal-list-folder-important
273   'elmo-generic-list-folder-important)
274 (defalias 'elmo-internal-commit 'elmo-generic-commit)
275
276 (provide 'elmo-internal)
277
278 ;;; elmo-internal.el ends here