1 ;;; wl-expire.el --- Message expire modules for Wanderlust.
3 ;; Copyright (C) 1998,1999,2000 Masahiro MURATA <muse@ba2.so-net.ne.jp>
4 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Author: Masahiro MURATA <muse@ba2.so-net.ne.jp>
7 ;; Keywords: mail, net news
9 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
11 ;; This program is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
39 (require 'elmo-archive))
43 (defvar wl-expired-alist nil)
44 (defvar wl-expired-alist-file-name "expired-alist")
45 (defvar wl-expired-log-alist nil)
46 (defvar wl-expired-log-alist-file-name "expired-log")
47 (defvar wl-expire-test nil) ;; for debug (no execute)
49 (defun wl-expired-alist-load ()
50 (elmo-object-load (expand-file-name
51 wl-expired-alist-file-name
52 elmo-msgdb-directory)))
54 (defun wl-expired-alist-save (&optional alist)
55 (elmo-object-save (expand-file-name
56 wl-expired-alist-file-name
58 (or alist wl-expired-alist)))
60 (defsubst wl-expire-msg-p (msg-num mark-alist)
61 (cond ((consp wl-summary-expire-reserve-marks)
62 (let ((mark (nth 1 (assq msg-num mark-alist))))
63 (not (or (member mark wl-summary-expire-reserve-marks)
64 (and wl-summary-buffer-disp-msg
65 (eq msg-num wl-summary-buffer-current-msg))))))
66 ((eq wl-summary-expire-reserve-marks 'all)
67 (not (or (assq msg-num mark-alist)
68 (and wl-summary-buffer-disp-msg
69 (eq msg-num wl-summary-buffer-current-msg)))))
70 ((eq wl-summary-expire-reserve-marks 'none)
73 (error "Invalid marks: %s" wl-summary-expire-reserve-marks))))
75 (defmacro wl-expire-make-sortable-date (date)
76 (` (timezone-make-sortable-date
77 (aref (, date) 0) (aref (, date) 1) (aref (, date) 2)
78 (timezone-make-time-string
79 (aref (, date) 3) (aref (, date) 4) (aref (, date) 5)))))
81 (defsubst wl-expire-date-p (key-datevec date)
82 (let ((datevec (condition-case nil
83 (timezone-fix-time date nil nil)
86 datevec (> (aref datevec 1) 0)
88 (wl-expire-make-sortable-date datevec)
89 (wl-expire-make-sortable-date key-datevec)))))
91 (defun wl-expire-delete-reserve-marked-msgs-from-list (msgs mark-alist)
94 (unless (wl-expire-msg-p (car dlist) mark-alist)
95 (setq msgs (delq (car dlist) msgs)))
96 (setq dlist (cdr dlist)))
99 (defun wl-expire-delete (folder delete-list msgdb &optional no-reserve-marks)
100 "Delete message for expire."
101 (unless no-reserve-marks
103 (wl-expire-delete-reserve-marked-msgs-from-list
104 delete-list (elmo-msgdb-get-mark-alist msgdb))))
107 (format "Expiring (delete) %s msgs..."
108 (length delete-list))))
110 (if (elmo-folder-delete-messages folder
113 (elmo-msgdb-delete-msgs (elmo-folder-msgdb folder)
115 (wl-expire-append-log
116 (elmo-folder-name-internal folder)
117 delete-list nil 'delete)
118 (message "%s" (concat mess "done")))
119 (error (concat mess "failed!")))))
120 (cons delete-list (length delete-list)))
122 (defun wl-expire-refile (folder refile-list msgdb dst-folder
123 &optional no-reserve-marks preserve-number copy)
124 "Refile message for expire. If COPY is non-nil, copy message."
125 (when (not (string= (elmo-folder-name-internal folder) dst-folder))
126 (unless no-reserve-marks
128 (wl-expire-delete-reserve-marked-msgs-from-list
129 refile-list (elmo-msgdb-get-mark-alist msgdb))))
131 (let* ((doingmes (if copy
133 "Expiring (move %s)"))
134 (dst-folder (wl-folder-get-elmo-folder dst-folder))
135 (mess (format (concat doingmes " %s msgs...")
136 (elmo-folder-name-internal dst-folder)
137 (length refile-list))))
141 (unless (or (elmo-folder-exists-p dst-folder)
142 (elmo-folder-create dst-folder))
143 (error "%s: create folder failed"
144 (elmo-folder-name-internal dst-folder)))
145 (if (elmo-folder-move-messages folder
153 wl-expire-add-seen-list)
155 (wl-expire-append-log
156 (elmo-folder-name-internal folder)
158 (elmo-folder-name-internal dst-folder)
159 (if copy 'copy 'move))
160 (message "%s" (concat mess "done")))
161 (error (concat mess "failed!"))))))
162 (cons refile-list (length refile-list))))
164 (defun wl-expire-refile-with-copy-reserve-msg
165 (folder refile-list msgdb dst-folder
166 &optional no-reserve-marks preserve-number copy)
167 "Refile message for expire.
168 If REFILE-LIST includes reserve mark message, so copy."
169 (when (not (string= (elmo-folder-name-internal folder) dst-folder))
170 (let ((msglist refile-list)
171 (mark-alist (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder)))
172 (number-alist (elmo-msgdb-get-number-alist (elmo-folder-msgdb
174 (dst-folder (wl-folder-get-elmo-folder dst-folder))
176 (copy-reserve-message)
179 (message "Expiring (move %s) %s msgs..."
180 (elmo-folder-name-internal dst-folder) (length refile-list))
182 (setq copy-len (length refile-list))
183 (unless (or (elmo-folder-exists-p dst-folder)
184 (elmo-folder-create dst-folder))
185 (error "%s: create folder failed" (elmo-folder-name-internal
187 (while (setq msg (wl-pop msglist))
188 (unless (wl-expire-msg-p msg mark-alist)
189 (setq msg-id (cdr (assq msg number-alist)))
190 (if (assoc msg-id wl-expired-alist)
191 ;; reserve mark message already refiled or expired
192 (setq refile-list (delq msg refile-list))
193 ;; reserve mark message not refiled
194 (wl-append wl-expired-alist (list (cons msg-id
195 (elmo-folder-name-internal
197 (setq copy-reserve-message t))))
201 (elmo-folder-move-messages folder
209 wl-expire-add-seen-list))
210 (error "Expire: move msgs to %s failed"
211 (elmo-folder-name-internal dst-folder)))
212 (wl-expire-append-log (elmo-folder-name-internal folder)
214 (elmo-folder-name-internal dst-folder)
215 (if copy-reserve-message 'copy 'move))
216 (setq copy-len (length refile-list))
217 (when copy-reserve-message
219 (wl-expire-delete-reserve-marked-msgs-from-list
224 (elmo-folder-delete-messages folder
227 (elmo-msgdb-delete-msgs (elmo-folder-msgdb folder)
229 (wl-expire-append-log
230 (elmo-folder-name-internal folder)
231 refile-list nil 'delete))))))
232 (let ((mes (format "Expiring (move %s) %s msgs..."
233 (elmo-folder-name-internal dst-folder)
234 (length refile-list))))
236 (message (concat mes "done"))
237 (error (concat mes "failed!")))))
238 (cons refile-list copy-len))))
240 (defun wl-expire-archive-get-folder (src-folder &optional fmt dst-folder-arg)
241 "Get archive folder name from SRC-FOLDER."
242 (let* ((fmt (or fmt wl-expire-archive-folder-name-fmt))
243 (src-folde-name (substring
244 (elmo-folder-name-internal src-folder)
245 (length (elmo-folder-prefix-internal src-folder))))
246 (archive-spec (char-to-string
247 (car (rassq 'archive elmo-folder-type-alist))))
248 dst-folder-base dst-folder-fmt prefix)
249 (cond (dst-folder-arg
250 (setq dst-folder-base (concat archive-spec dst-folder-arg)))
251 ((eq (elmo-folder-type-internal src-folder) 'localdir)
252 (setq dst-folder-base
253 (concat archive-spec src-folde-name)))
255 (setq dst-folder-base
257 (format "%s%s" archive-spec (elmo-folder-type-internal
260 (setq dst-folder-fmt (format fmt
262 wl-expire-archive-folder-type))
263 (setq dst-folder-base (format "%s;%s"
265 wl-expire-archive-folder-type))
266 (when wl-expire-archive-folder-prefix
267 (cond ((eq wl-expire-archive-folder-prefix 'short)
268 (setq prefix (file-name-nondirectory
271 (setq prefix src-folde-name)))
272 (setq dst-folder-fmt (concat dst-folder-fmt ";" prefix))
273 (setq dst-folder-base (concat dst-folder-base ";" prefix)))
274 (cons dst-folder-base dst-folder-fmt)))
276 (defsubst wl-expire-archive-get-max-number (dst-folder-base &optional regexp)
277 (let ((files (reverse (sort (elmo-folder-list-subfolders
278 (elmo-make-folder dst-folder-base))
280 (regexp (or regexp wl-expire-archive-folder-num-regexp))
284 (when (string-match regexp (car files))
285 (setq filenum (elmo-match-string 1 (car files)))
286 (setq in-folder (elmo-folder-status
287 (wl-folder-get-elmo-folder (car files))))
288 (throw 'done (cons in-folder filenum)))
289 (setq files (cdr files))))))
291 (defun wl-expire-archive-number-delete-old (dst-folder-base
292 preserve-number msgs mark-alist
293 &optional no-confirm regexp file)
294 (let ((len 0) (max-num 0)
296 (if (or (and file (setq folder-info
297 (cons (elmo-folder-status
298 (wl-folder-get-elmo-folder file))
300 (setq folder-info (wl-expire-archive-get-max-number
304 (setq len (cdar folder-info))
305 (when preserve-number
306 ;; delete small number than max number of dst-folder
307 (setq max-num (caar folder-info))
308 (while (and msgs (>= max-num (car msgs)))
309 (wl-append dels (list (car msgs)))
310 (setq msgs (cdr msgs)))
311 (setq dels (wl-expire-delete-reserve-marked-msgs-from-list
314 (or (or no-confirm (not wl-expire-delete-oldmsg-confirm))
316 (if (eq major-mode 'wl-summary-mode)
317 (wl-thread-jump-to-msg (car dels)))
318 (y-or-n-p (format "Delete old messages %s? "
321 (list msgs dels max-num (cdr folder-info) len))
322 (list msgs dels 0 "0" 0))))
324 (defun wl-expire-archive-number1 (folder delete-list msgdb
325 &optional preserve-number dst-folder-arg
327 "Standard function for `wl-summary-expire'.
328 Refile to archive folder followed message number."
329 (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file.
330 (dst-folder-expand (and dst-folder-arg
333 (elmo-folder-name-internal folder))))
334 (dst-folder-fmt (funcall
335 wl-expire-archive-get-folder-function
336 folder nil dst-folder-expand))
337 (dst-folder-base (car dst-folder-fmt))
338 (dst-folder-fmt (cdr dst-folder-fmt))
339 (refile-func (if no-delete
341 'wl-expire-refile-with-copy-reserve-msg))
343 prev-arcnum arcnum msg arcmsg-list
344 deleted-list ret-val)
345 (setq tmp (wl-expire-archive-number-delete-old
346 dst-folder-base preserve-number delete-list
347 (elmo-msgdb-get-mark-alist msgdb)
349 (when (and (not no-delete)
350 (setq dels (nth 1 tmp)))
351 (wl-append deleted-list (car (wl-expire-delete folder dels msgdb))))
352 (setq delete-list (car tmp))
355 (if (setq msg (wl-pop delete-list))
356 (setq arcnum (/ msg wl-expire-archive-files))
358 (when (and prev-arcnum
359 (not (eq arcnum prev-arcnum)))
360 (setq dst-folder (format dst-folder-fmt
361 (* prev-arcnum wl-expire-archive-files)))
365 folder arcmsg-list msgdb dst-folder t preserve-number
367 (wl-append deleted-list (car ret-val)))
368 (setq arcmsg-list nil))
371 (wl-append arcmsg-list (list msg))
372 (setq prev-arcnum arcnum)))
375 (defun wl-expire-archive-number2 (folder delete-list msgdb
376 &optional preserve-number dst-folder-arg
378 "Standard function for `wl-summary-expire'.
379 Refile to archive folder followed the number of message in one archive folder."
380 (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file.
381 (dst-folder-expand (and dst-folder-arg
384 (elmo-folder-name-internal folder))))
385 (dst-folder-fmt (funcall
386 wl-expire-archive-get-folder-function
387 folder nil dst-folder-expand))
388 (dst-folder-base (car dst-folder-fmt))
389 (dst-folder-fmt (cdr dst-folder-fmt))
390 (refile-func (if no-delete
392 'wl-expire-refile-with-copy-reserve-msg))
395 arc-len msg arcmsg-list
396 deleted-list ret-val)
397 (setq tmp (wl-expire-archive-number-delete-old
398 dst-folder-base preserve-number delete-list
399 (elmo-msgdb-get-mark-alist msgdb)
401 (when (and (not no-delete)
402 (setq dels (nth 1 tmp)))
403 (wl-append deleted-list (car (wl-expire-delete folder dels msgdb))))
404 (setq delete-list (car tmp)
405 filenum (string-to-int (nth 3 tmp))
410 (if (setq msg (wl-pop delete-list))
412 (setq len (1+ wl-expire-archive-files)))
413 (when (> len wl-expire-archive-files)
415 (setq dst-folder (format dst-folder-fmt filenum))
419 folder arcmsg-list msgdb dst-folder t preserve-number
421 (wl-append deleted-list (car ret-val)))
422 (setq arc-len (+ arc-len (cdr ret-val))))
423 (setq arcmsg-list nil)
424 (if (< arc-len wl-expire-archive-files)
425 (setq len (1+ arc-len))
426 (setq filenum (+ filenum wl-expire-archive-files)
427 len (- len arc-len) ;; maybe 1
428 arc-len (1- len) ;; maybe 0
432 (wl-append arcmsg-list (list msg))))
435 (defun wl-expire-archive-date (folder delete-list msgdb
436 &optional preserve-number dst-folder-arg
438 "Standard function for `wl-summary-expire'.
439 Refile to archive folder followed message date."
440 (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file.
441 (number-alist (elmo-msgdb-get-number-alist msgdb))
442 (overview (elmo-msgdb-get-overview msgdb))
443 (dst-folder-expand (and dst-folder-arg
446 (elmo-folder-name-internal folder))))
447 (dst-folder-fmt (funcall
448 wl-expire-archive-get-folder-function
450 wl-expire-archive-date-folder-name-fmt
453 (dst-folder-base (car dst-folder-fmt))
454 (dst-folder-fmt (cdr dst-folder-fmt))
455 (refile-func (if no-delete
457 'wl-expire-refile-with-copy-reserve-msg))
458 tmp dels dst-folder date time
459 msg arcmsg-alist arcmsg-list
460 deleted-list ret-val)
461 (setq tmp (wl-expire-archive-number-delete-old
462 dst-folder-base preserve-number delete-list
463 (elmo-msgdb-get-mark-alist msgdb)
465 wl-expire-archive-date-folder-num-regexp))
466 (when (and (not no-delete)
467 (setq dels (nth 1 tmp)))
468 (wl-append deleted-list (car (wl-expire-delete folder dels msgdb))))
469 (setq delete-list (car tmp))
470 (while (setq msg (wl-pop delete-list))
471 (setq date (elmo-msgdb-overview-entity-get-date
472 (assoc (cdr (assq msg number-alist)) overview)))
475 (timezone-fix-time date nil nil)
476 (error [0 0 0 0 0 0 0])))
477 (if (= (aref time 1) 0) ;; if (month == 0)
478 (aset time 0 0)) ;; year = 0
479 (setq dst-folder (format dst-folder-fmt
480 (aref time 0) ;; year
481 (aref time 1) ;; month
484 (wl-append-assoc-list
489 (setq dst-folder (caar arcmsg-alist))
490 (setq arcmsg-list (cdar arcmsg-alist))
494 folder arcmsg-list msgdb dst-folder t preserve-number
496 (wl-append deleted-list (car ret-val)))
497 (setq arcmsg-alist (cdr arcmsg-alist)))
500 ;;; wl-expire-localdir-date
501 (defvar wl-expire-localdir-date-folder-name-fmt "%s/%%04d_%%02d")
503 (defcustom wl-expire-localdir-get-folder-function
504 'wl-expire-localdir-get-folder
505 "*A function to get localdir folder name."
509 (defun wl-expire-localdir-get-folder (src-folder fmt dst-folder-arg)
510 "Get localdir folder name from src-folder."
511 (let* ((src-folder-name (substring
512 (elmo-folder-name-internal src-folder)
513 (length (elmo-folder-prefix-internal src-folder))))
514 (dst-folder-spec (char-to-string
515 (car (rassq 'localdir elmo-folder-type-alist))))
516 dst-folder-base dst-folder-fmt)
517 (cond (dst-folder-arg
518 (setq dst-folder-base (concat dst-folder-spec dst-folder-arg)))
519 ((eq (elmo-folder-type-internal src-folder) 'localdir)
520 (setq dst-folder-base (concat dst-folder-spec src-folder-name)))
522 (setq dst-folder-base
526 (elmo-folder-type-internal src-folder))
529 (format fmt dst-folder-base))
530 (cons dst-folder-base dst-folder-fmt)))
532 (defun wl-expire-localdir-date (folder delete-list msgdb
533 &optional preserve-number dst-folder-arg
535 "Function for `wl-summary-expire'.
536 Refile to localdir folder by message date.
537 ex. +ml/wl/1999_11/, +ml/wl/1999_12/."
538 (let* ((number-alist (elmo-msgdb-get-number-alist msgdb))
539 (overview (elmo-msgdb-get-overview msgdb))
540 (dst-folder-expand (and dst-folder-arg
543 (elmo-folder-name-internal folder))))
544 (dst-folder-fmt (funcall
545 wl-expire-localdir-get-folder-function
547 wl-expire-localdir-date-folder-name-fmt
549 (dst-folder-base (car dst-folder-fmt))
550 (dst-folder-fmt (cdr dst-folder-fmt))
551 (refile-func (if no-delete
553 'wl-expire-refile-with-copy-reserve-msg))
554 tmp dels dst-folder date time
555 msg arcmsg-alist arcmsg-list
556 deleted-list ret-val)
557 (while (setq msg (wl-pop delete-list))
558 (setq date (elmo-msgdb-overview-entity-get-date
559 (assoc (cdr (assq msg number-alist)) overview)))
562 (timezone-fix-time date nil nil)
563 (error [0 0 0 0 0 0 0])))
564 (if (= (aref time 1) 0) ;; if (month == 0)
565 (aset time 0 0)) ;; year = 0
566 (setq dst-folder (format dst-folder-fmt
568 (aref time 1);; month
571 (wl-append-assoc-list
576 (setq dst-folder (caar arcmsg-alist))
577 (setq arcmsg-list (cdar arcmsg-alist))
581 folder arcmsg-list msgdb dst-folder t preserve-number
583 (wl-append deleted-list (car ret-val)))
584 (setq arcmsg-alist (cdr arcmsg-alist)))
587 (defun wl-expire-hide (folder hide-list msgdb &optional no-reserve-marks)
588 "Hide message for expire."
589 (unless no-reserve-marks
591 (wl-expire-delete-reserve-marked-msgs-from-list
592 hide-list (elmo-msgdb-get-mark-alist msgdb))))
593 (let ((mess (format "Hiding %s msgs..." (length hide-list))))
595 (elmo-msgdb-delete-msgs (elmo-folder-msgdb folder) hide-list)
596 (elmo-msgdb-append-to-killed-list folder hide-list)
597 (elmo-folder-commit folder)
598 (message (concat mess "done"))
599 (cons hide-list (length hide-list))))
601 (defsubst wl-expire-folder-p (entity)
602 "Return non-nil, when ENTITY matched `wl-expire-alist'."
603 (wl-get-assoc-list-value wl-expire-alist entity))
605 (defsubst wl-archive-folder-p (entity)
606 "Return non-nil, when ENTITY matched `wl-archive-alist'."
607 (wl-get-assoc-list-value wl-archive-alist entity))
609 (defun wl-summary-expire (&optional folder notsummary nolist)
612 (let ((folder (or folder wl-summary-buffer-elmo-folder))
613 (deleting-info "Expiring...")
615 (when (and (or (setq expires (wl-expire-folder-p
616 (elmo-folder-name-internal folder)))
617 (progn (and (interactive-p)
618 (message "no match %s in wl-expire-alist"
619 (elmo-folder-name-internal folder)))
621 (or (not (interactive-p))
622 (y-or-n-p (format "Expire %s? " (elmo-folder-name-internal
624 (let* ((msgdb (or (wl-summary-buffer-msgdb)
625 (progn (elmo-folder-open folder 'load-msgdb)
626 (elmo-folder-msgdb folder))))
627 (number-alist (elmo-msgdb-get-number-alist msgdb))
628 (mark-alist (elmo-msgdb-get-mark-alist msgdb))
629 expval rm-type val-type value more args
632 (setq expval (car expires)
633 rm-type (nth 1 expires)
635 (setq val-type (car expval)
638 (run-hooks 'wl-summary-expire-pre-hook)
641 ((eq val-type 'number)
642 (let* ((msgs (if (not nolist)
643 (elmo-folder-list-messages folder)
644 (mapcar 'car number-alist)))
645 (msglen (length msgs))
646 (more (or more (1+ value)))
648 (when (>= msglen more)
649 (setq count (- msglen value))
650 (while (and msgs (> count 0))
651 (when (assq (car msgs) number-alist) ;; don't expire new message
652 (wl-append delete-list (list (car msgs)))
653 (when (or (not wl-expire-number-with-reserve-marks)
654 (wl-expire-msg-p (car msgs) mark-alist))
655 (setq count (1- count))))
656 (setq msgs (cdr msgs))))))
658 (let* ((overview (elmo-msgdb-get-overview msgdb))
659 (key-date (elmo-date-get-offset-datevec
660 (timezone-fix-time (current-time-string)
661 (current-time-zone) nil)
664 (when (wl-expire-date-p
666 (elmo-msgdb-overview-entity-get-date
668 (wl-append delete-list
669 (list (elmo-msgdb-overview-entity-get-number
671 (setq overview (cdr overview)))))
673 (error "%s: not supported" val-type)))
676 (setq wl-expired-alist (wl-expired-alist-load)))
677 ;; evaluate string-match for wl-expand-newtext
679 (elmo-folder-name-internal folder))
681 (cond ((eq rm-type nil) nil)
682 ((eq rm-type 'remove)
683 (setq deleting-info "Deleting...")
684 (car (wl-expire-delete folder delete-list msgdb)))
686 (setq deleting-info "Deleting...")
687 (car (wl-expire-refile folder delete-list msgdb wl-trash-folder)))
689 (setq deleting-info "Hiding...")
690 (car (wl-expire-hide folder delete-list msgdb)))
692 (setq deleting-info "Refiling...")
693 (car (wl-expire-refile folder delete-list msgdb
696 (elmo-folder-name-internal folder)))))
698 (apply rm-type (append (list folder delete-list msgdb)
701 (error "%s: invalid type" rm-type))))
702 (when (and (not wl-expire-test) (not notsummary) delete-list)
703 (wl-summary-delete-messages-on-buffer delete-list deleting-info)
704 (wl-summary-folder-info-update)
705 (wl-summary-set-message-modified)
706 (wl-summary-set-mark-modified)
708 (set-buffer-modified-p nil))
709 (wl-expired-alist-save))
710 (run-hooks 'wl-summary-expire-hook)
712 (message "Expiring %s is done" (elmo-folder-name-internal
715 (message "No expire"))))
718 (defun wl-folder-expire-entity (entity)
721 (let ((flist (nth 2 entity)))
723 (wl-folder-expire-entity (car flist))
724 (setq flist (cdr flist)))))
726 (when (wl-expire-folder-p entity)
727 (let* ((folder (wl-folder-get-elmo-folder entity))
729 ((consp wl-expire-folder-update-msgdb)
730 (wl-string-match-member
732 wl-expire-folder-update-msgdb))
734 wl-expire-folder-update-msgdb)))
735 (wl-summary-highlight (if (or (wl-summary-sticky-p folder)
736 (wl-summary-always-sticky-folder-p
738 wl-summary-highlight))
739 wl-auto-select-first ret-val)
740 (save-window-excursion
743 (wl-summary-goto-folder-subr entity 'force-update nil))
744 (setq ret-val (wl-summary-expire folder (not update-msgdb)))
747 (wl-summary-save-view)
748 (elmo-folder-commit wl-summary-buffer-elmo-folder))
750 (wl-folder-check-entity entity))))))))))
754 (defun wl-folder-expire-current-entity ()
757 (or (wl-folder-get-folder-name-by-id
758 (get-text-property (point) 'wl-folder-entity-id))
759 (wl-folder-get-realname (wl-folder-folder-name)))))
760 (when (and entity-name
761 (or (not (interactive-p))
762 (y-or-n-p (format "Expire %s? " entity-name))))
763 (wl-folder-expire-entity
764 (wl-folder-search-entity-by-name entity-name
766 (if (get-buffer wl-summary-buffer-name)
767 (kill-buffer wl-summary-buffer-name))
768 (message "Expiring %s is done" entity-name))))
772 (defun wl-folder-archive-current-entity ()
775 (or (wl-folder-get-folder-name-by-id
776 (get-text-property (point) 'wl-folder-entity-id))
777 (wl-folder-get-realname (wl-folder-folder-name)))))
778 (when (and entity-name
779 (or (not (interactive-p))
780 (y-or-n-p (format "Archive %s? " entity-name))))
781 (wl-folder-archive-entity
782 (wl-folder-search-entity-by-name entity-name
784 (message "Archiving %s is done" entity-name))))
786 (defun wl-archive-number1 (folder archive-list msgdb &optional dst-folder-arg)
787 (wl-expire-archive-number1 folder archive-list msgdb t dst-folder-arg t))
789 (defun wl-archive-number2 (folder archive-list msgdb &optional dst-folder-arg)
790 (wl-expire-archive-number2 folder archive-list msgdb t dst-folder-arg t))
792 (defun wl-archive-date (folder archive-list msgdb &optional dst-folder-arg)
793 (wl-expire-archive-date folder archive-list msgdb t dst-folder-arg t))
795 (defun wl-archive-folder (folder archive-list msgdb dst-folder)
796 (let* ((elmo-archive-treat-file t) ;; treat archive folder as a file.
799 (car (wl-expire-archive-number-delete-old
801 (elmo-msgdb-get-mark-alist msgdb)
807 folder archive-list msgdb dst-folder t t t)) ;; copy!!
808 (wl-append copied-list ret-val)))
811 (defun wl-summary-archive (&optional arg folder notsummary nolist)
814 (let* ((folder (or folder wl-summary-buffer-elmo-folder))
815 (msgdb (or (wl-summary-buffer-msgdb)
816 (elmo-msgdb-load folder)))
817 (msgs (if (not nolist)
818 (elmo-folder-list-messages folder)
819 (mapcar 'car (elmo-msgdb-get-number-alist msgdb))))
820 (alist wl-archive-alist)
821 archives func args dst-folder archive-list)
823 (let ((wl-default-spec (char-to-string
825 elmo-folder-type-alist)))))
826 (setq dst-folder (wl-summary-read-folder
827 (concat wl-default-spec
829 (elmo-folder-name-internal folder) 1))
831 (run-hooks 'wl-summary-archive-pre-hook)
833 (wl-archive-folder folder msgs msgdb dst-folder)
834 (when (and (or (setq archives (wl-archive-folder-p
835 (elmo-folder-name-internal folder)))
836 (progn (and (interactive-p)
837 (message "No match %s in wl-archive-alist"
838 (elmo-folder-name-internal folder)))
840 (or (not (interactive-p))
841 (y-or-n-p (format "Archive %s? "
842 (elmo-folder-name-internal folder)))))
843 (setq func (car archives)
846 (apply func (append (list folder msgs msgdb) args)))
847 (run-hooks 'wl-summary-archive-hook)
849 (message "Archiving %s is done" (elmo-folder-name-internal folder))
851 (message "No archive")))))))
853 (defun wl-folder-archive-entity (entity)
856 (let ((flist (nth 2 entity)))
858 (wl-folder-archive-entity (car flist))
859 (setq flist (cdr flist)))))
861 (wl-summary-archive nil (wl-folder-get-elmo-folder entity) t))))
865 (defun wl-expire-append-log (src-folder msgs dst-folder action)
866 (when wl-expire-use-log
868 (let ((tmp-buf (get-buffer-create " *wl-expire work*"))
869 (filename (expand-file-name wl-expired-log-alist-file-name
870 elmo-msgdb-directory)))
874 (insert (format "%s\t%s -> %s\t%s\n"
876 src-folder dst-folder msgs))
877 (insert (format "%s\t%s\t%s\n"
880 (if (file-writable-p filename)
881 (write-region (point-min) (point-max)
883 (message (format "%s is not writable." filename)))
884 (kill-buffer tmp-buf)))))
887 (product-provide (provide 'wl-expire) (require 'wl-version))
889 ;;; wl-expire.el ends here